hdoj 2066 一个人的旅行

时间:2021-03-11 03:50:33
Problem Description
虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
 
Input
输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。
 
Output
输出草儿能去某个喜欢的城市的最短时间。
 
Sample Input
6 2 3 1 3 5 1 4 7 2 8 12 3 8 4 4 9 12 9 10 2 1 2 8 9 10
 
Sample Output
9
 
思路:以草儿家相邻的城市为起点,以草儿想去的城市为终点
 
dijkstra算法:
 #include <stdio.h>
#include <algorithm>
#define INF 0x3f3f3f3f
#define N 1010
using namespace std;
int s, t, d, wp[N], nei[N];
int vis[N], cost[N][N], dis[N];
int min(int x, int y)
{
return x<y ? x : y;
}
void dijkstra(int i)
{ int u, v;
for(u = ; u <= N; u++)
{
dis[u] = INF;
vis[u] = ;
}
dis[nei[i]] = ;
while(true)
{
v = -;
for(u = ; u <= ; u++)
if(!vis[u] && (v==- || dis[u] < dis[v]))
v = u;
if(v == -)
break;
vis[v] = ;
for(u = ; u <= ; u++)
dis[u] = min(dis[u], dis[v]+cost[v][u]);
}
}
int main()
{
int i, j;
while(~scanf("%d%d%d", &t, &s, &d))
{
for(i = ; i < ; i++)
for(j = i; j <= ; j++)
cost[i][j] = cost[j][i] = INF;
int a, b, c;
while(t--)
{
scanf("%d%d%d", &a, &b, &c);
if(cost[a][b] > c)
cost[a][b] = cost[b][a] = c;
}
for(i = ; i <= s; i++)
scanf("%d", &nei[i]);
for(i = ; i <= d; i++)
scanf("%d", &wp[i]);
int min = INF;
for(i = ; i <= s; i++)
{
dijkstra(i);
for(j = ; j <= d; j++)
{
if(min>dis[wp[j]])
min = dis[wp[j]];
}
}
printf("%d\n", min);
//printf("%d\n", q.top());
}
return ;
}

spfa算法不用以终点为起点,只要在输入起点的时候将该点进入队列就行了

spfa代码:

 #include <stdio.h>
#include <string.h>
#include <queue>
# define INF 0x3f3f3f3f
#define N 110
#define M 450
using namespace std; struct node
{
int from, to, val, next;
};
node edge[M];
int n, m, cnt;
int dis[N], vis[N], head[N];
void add(int x, int y)
{
node e = {x, y, , head[x]};
edge[cnt] = e;
head[x] = cnt++;
}
void SPFA(int s)
{
queue<int>q;
memset(vis, , sizeof(vis));
memset(dis, INF, sizeof(dis));
q.push(s);
vis[s] = ;
dis[s] = ;
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = ;
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(dis[v] > dis[u] + edge[i].val)
{
dis[v] = dis[u] + edge[i].val;
if(!vis[v])
{
vis[v] = ;
q.push(v);
}
}
}
}
}
int main()
{
while(~scanf("%d%d", &n, &m))
{
cnt = ;
int flag = ;
memset(head, -, sizeof(head));
while(m--)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
add(b, a);
}
for(int i = ; i < n; i++)
{
SPFA(i);
for(int j = ; j < n; j++)
{
if(dis[j] > )
{
flag = ;
break;
}
}
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return ;
}

floyd算法:

 #include <stdio.h>
#define INF 0x3f3f3f3f
#define N 1010
int dis[N][N];
int m;
void init()
{
for(int i = ; i < N; i++)
for(int j = ; j < N; j++)
{
if(i == j)
dis[i][j] = ;
else
dis[i][j] = INF;
}
}
int max(int x, int y)
{
return x > y ? x : y;
}
void floyd()
{
for(int k = ; k <= m; k++)
for(int i = ; i <= m; i++)
{
if(dis[i][k] != INF)//如果这一步不判断的话,代码会超时
for(int j = ; j <= m; j++)
{
if(dis[i][j] > dis[i][k] + dis[k][j])
dis[i][j] = dis[i][k] + dis[k][j];
}
}
}
int main()
{
int t, s, d;
int a, b, time;
while(~scanf("%d%d%d", &t, &s, &d))
{
m = ;
init();
while(t--)
{
scanf("%d%d%d", &a, &b, &time);
if(dis[a][b] > time)
dis[a][b] = dis[b][a] = time;
if(m < a)
m = a;
if(m < b)
m = b;
}
while(s--)
{
scanf("%d", &a);
dis[][a] = dis[a][] = ;
}
floyd();
int min = INF;
while(d--)
{
scanf("%d", &a);
if(min > dis[][a])
min = dis[][a];
}
printf("%d\n", min);
}
return ;
}