hdoj 2066 一个人的旅行

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算法:
 1 #include <stdio.h>
 2 #include <algorithm>
 3 #define INF 0x3f3f3f3f
 4 #define N 1010
 5 using namespace std;
 6 int s, t, d, wp[N], nei[N];
 7 int vis[N], cost[N][N], dis[N];
 8 int min(int x, int y)
 9 {
10     return x<y ? x : y;
11 }
12 void dijkstra(int i)
13 {
14     
15     int u, v;
16     for(u = 1; u <= N; u++)
17     {
18         dis[u] = INF;
19         vis[u] = 0;
20     }
21     dis[nei[i]] = 0;
22     while(true)
23     {
24         v = -1;
25         for(u = 1; u <= 1000; u++)
26             if(!vis[u] && (v==-1 || dis[u] < dis[v]))
27                 v = u;
28         if(v == -1)
29             break;
30         vis[v] = 1;
31         for(u = 1; u <= 1000; u++)
32             dis[u] = min(dis[u], dis[v]+cost[v][u]);
33     }
34 }
35 int main()
36 {
37     int i, j;
38     while(~scanf("%d%d%d", &t, &s, &d))
39     {
40         for(i = 1; i < 1000; i++)
41             for(j = i; j <= 1000; j++)
42                 cost[i][j] = cost[j][i] = INF;
43         int a, b, c;
44         while(t--)
45         {
46             scanf("%d%d%d", &a, &b, &c);
47             if(cost[a][b] > c)
48                 cost[a][b] = cost[b][a] = c;
49         }
50         for(i = 1; i <= s; i++)
51             scanf("%d", &nei[i]);
52         for(i = 1; i <= d; i++)
53             scanf("%d", &wp[i]);
54         int min = INF;
55         for(i = 1; i <= s; i++)
56         {
57             dijkstra(i);
58             for(j = 1; j <= d; j++)
59             {
60                 if(min>dis[wp[j]])
61                     min = dis[wp[j]];
62             }
63         }
64         printf("%d\n", min);
65         //printf("%d\n", q.top());
66     }
67     return 0;
68 }

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

spfa代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <queue>
 4 # define INF 0x3f3f3f3f
 5 #define N 110
 6 #define M 450
 7 using namespace std;
 8 
 9 struct node
10 {
11     int from, to, val, next;
12 };
13 node edge[M];
14 int n, m, cnt;
15 int dis[N], vis[N], head[N];
16 void add(int x, int y)
17 {
18     node e = {x, y, 1, head[x]};
19     edge[cnt] = e;
20     head[x] = cnt++;
21 }
22 void SPFA(int s)
23 {
24     queue<int>q;
25     memset(vis, 0, sizeof(vis));
26     memset(dis, INF, sizeof(dis));
27     q.push(s);
28     vis[s] = 1;
29     dis[s] = 0;
30     while(!q.empty())
31     {
32         int u = q.front();
33         q.pop();
34         vis[u] = 0;
35         for(int i = head[u]; i != -1; i = edge[i].next)
36         {
37             int v = edge[i].to;
38             if(dis[v] > dis[u] + edge[i].val)
39             {
40                 dis[v] = dis[u] + edge[i].val;
41                 if(!vis[v])
42                 {
43                     vis[v] = 1;
44                     q.push(v);
45                 }
46             }
47         }
48     }
49 }
50 int main()
51 {
52     while(~scanf("%d%d", &n, &m))
53     {
54         cnt = 0;
55         int flag = 1;
56         memset(head, -1, sizeof(head));
57         while(m--)
58         {
59             int a, b;
60             scanf("%d%d", &a, &b);
61             add(a, b);
62             add(b, a);
63         }
64         for(int i = 0; i < n; i++)
65         {
66             SPFA(i);
67             for(int j = 0; j < n; j++)
68             {
69                 if(dis[j] > 7)
70                 {
71                     flag = 0;
72                     break;
73                 }
74             }
75         }
76         if(flag)
77             printf("Yes\n");
78         else
79             printf("No\n");
80     }
81     return 0;
82 }

 floyd算法:

 1 #include <stdio.h>
 2 #define INF 0x3f3f3f3f
 3 #define N 1010
 4 int dis[N][N];
 5 int m;
 6 void init()
 7 {
 8     for(int i = 0; i < N; i++)
 9     for(int j = 0; j < N; j++)
10         {
11             if(i == j)
12                 dis[i][j] = 0;
13             else
14                 dis[i][j] = INF;
15         }
16 }
17 int max(int x, int y)
18 {
19     return x > y ? x : y;
20 } 
21 void floyd()
22 {
23     for(int k = 0; k <= m; k++)
24         for(int i = 0; i <= m; i++)
25         {
26             if(dis[i][k] != INF)//如果这一步不判断的话,代码会超时 
27                 for(int j = 0; j <= m; j++)
28                 {
29                     if(dis[i][j] > dis[i][k] + dis[k][j])
30                         dis[i][j] = dis[i][k] + dis[k][j];
31                 }
32         }
33 }
34 int main()
35 {
36     int t, s, d;
37     int a, b, time;
38     while(~scanf("%d%d%d", &t, &s, &d))
39     {
40         m = 0;
41         init();
42         while(t--)
43         {
44             scanf("%d%d%d", &a, &b, &time);
45             if(dis[a][b] > time) 
46                 dis[a][b] = dis[b][a] = time;
47             if(m < a)
48                 m = a;
49             if(m < b)
50                 m = b; 
51         } 
52         while(s--)
53         {
54             scanf("%d", &a);
55             dis[0][a] = dis[a][0] = 0;
56         }
57         floyd();
58         int min = INF;
59         while(d--)
60         {
61             scanf("%d", &a);
62             if(min > dis[0][a])
63                 min = dis[0][a];
64         }
65         printf("%d\n", min);
66     }
67     return 0;
68 }

 

posted on 2015-08-18 09:56  帝孤  阅读(156)  评论(0编辑  收藏  举报

导航