HDU 2066 一个人的旅行(Dijkstra+Floyd)

一个人的旅行

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12103    Accepted Submission(s): 4111

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
 
Author
Grass
 
Source
 
Recommend
lcy
 

PS:表示这题提交了好多次。。。。。一开始用Floyd算法提交超时了,然后各种修改……还是不行,后来又改Dijkstra算法,参考了下discuss那的代码,结果又因为那最大值取小了WA了好几次(题目说a,b<=1000,我就取1001了,惨痛的教训啊)。。。虽然用Dijkstra算法过了,但是自己纳闷了,为啥用Floyd算法就超时了呢?还好discuss那有Floyd算法的代码可以参考下,经过多次TLE之后,总算AC了。。。。艰难的最短路啊

思路:

1>Dijkstra算法:因为开始的点有多个,可以构造一个虚拟起点,让所有的起点指向该虚拟起点,即虚拟起点到各起点之间距离为0,同时,构造一个虚拟终点,让所有的终点指向该虚拟终点,之后就可以放心使用Dijkstra算法了

 

2>Floyd算法:可以设置两个标志数组,一个设置起点标志为1(或true),一个设置终点标志为1(或true),然后在Floyd算法核心部分加上判断:预设一个变量,只要遍历的点包含起点和终点,就将其与预设变量进行比较,存储最小值,从而得到最短时间。注意此时代码提交会TLE,应在第二重循环部分添加一行:if(g[i][k]!=MAX)(额,变量视自己代码而定吧)

 

特别注意:本题有重边。。。。。

 

 Dijkstra代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define N 1000+2
 5 #define MAX 9999999
 6 using namespace std;
 7 int g[N][N],n,d[N];
 8 void init()
 9 {
10     int i,j;
11     for(i=0;i<N;i++)
12     for(j=0;j<N;j++)
13     {
14         if(i==j)g[i][j]=0;
15         else g[i][j]=MAX;
16     }
17 }
18 void getd(int t,int a,int b)
19 {
20     int i,j,temp,max=0,s;
21     while(t--)
22     {
23         scanf("%d %d %d",&i,&j,&temp);
24         if(g[i][j]>temp)g[i][j]=g[j][i]=temp;
25         if(i>max)max=i;
26         if(j>max)max=j;
27     }
28     n=++max;
29     while(a--)
30     {
31         scanf("%d",&s);
32         g[s][0]=g[0][s]=d[s]=0;
33     }
34     while(b--)
35     {
36         scanf("%d",&s);
37         g[s][n]=g[n][s]=0;
38     }
39 }
40 int Dijkstra(int s,int t)
41 {
42     int i,j,w,minc,mark[N];
43     for (i=0;i<=n;i++)
44     { 
45         if(i==s){mark[s]=1;d[s]=0;}
46         else
47         {
48             d[i]=g[s][i];
49             mark[i]=0;
50         } 
51     }
52     for (i=1;i<=n;i++)
53     {
54         minc=MAX;
55         w=0;
56         for (j=1;j<=n;j++)
57         if (!mark[j]&&minc>d[j]) {minc=d[j];w=j;}
58         mark[w]=1;
59         for (j=0;j<=n;j++)
60         if (!mark[j]&&(g[w][j]<MAX)&&(d[j]>d[w]+g[w][j]))d[j]=d[w]+g[w][j];
61     }
62     return d[t];
63 }
64 int main()
65 {
66     int t,a,b;
67     while(scanf("%d %d %d",&t,&a,&b)!=EOF)
68     {
69         init();
70         getd(t,a,b);
71         printf("%d\n",Dijkstra(0,n));
72     }
73     return 0;
74 }

 

Floyd代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #define N 1010
 5 #define MAX 9999999
 6 using namespace std;
 7 int g[N][N], n, flag1[N], flag2[N];
 8 void init()
 9 {
10     int i, j;
11     for(i = 0; i < N; i++)
12         for(j = 0; j < N; j++)
13         {
14             if(i == j)g[i][j] = 0;
15             else g[i][j] = MAX;
16         }
17 }
18 void getd(int t, int a, int b)
19 {
20     int s, i, j, temp;
21     while(t--)
22     {
23         scanf("%d %d %d", &i, &j, &temp);
24         if(g[i][j] > temp)g[i][j] = g[j][i] = temp;
25         if(i > n)n = i;
26         if(j > n)n = j;
27     }
28     memset(flag1, 0, sizeof(flag1));
29     memset(flag2, 0, sizeof(flag2));
30     while(a--)
31     {
32         scanf("%d", &s);
33         flag1[s] = 1;
34     }
35     while(b--)
36     {
37         scanf("%d", &s);
38         flag2[s] = 1;
39     }
40 }
41 void floyd()
42 {
43     int i, j, k, temp = MAX;
44     for(k = 1; k <= n; k++)
45     {
46         for(i = 1; i <= n; i++)
47         {
48             if(g[i][k] != MAX)
49                 for(j = 1; j <= n; j++)
50                 {
51                     if(g[i][j] > g[i][k] + g[k][j])
52                         g[i][j] = g[i][k] + g[k][j];
53                     if(flag1[i] && flag2[j] && g[i][j] < temp)
54                         temp = g[i][j];
55                 }
56         }
57     }
58     printf("%d\n", temp);
59 }
60 int main()
61 {
62     int t, a, b, s, i, j, temp;
63     while(scanf("%d %d %d", &t, &a, &b) != EOF)
64     {
65         init();
66         getd(t, a, b);
67         floyd();
68     }
69     return 0;
70 }


 

 

posted @ 2013-03-28 21:44  LFENG  阅读(337)  评论(0编辑  收藏  举报