HDU-2066-一个人的旅行(多源到多源最短路)
Posted 芹菜菜园子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU-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
思路:两种方法,一种是直接多次Dijk算法,但要注意把各个初始节点之间的距离设为0,否则会RuntimeError。另一种比较巧妙,设一个0节点(草儿家),更新0节点到初始节点距离为0,就转化为单源到多源问题了,一个Dijk就Ok。
法一:
1 //各个初始节点之间距离为0 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define Inf 0x3f3f3f3f 6 #define N 1005 7 using namespace std; 8 int T,S,D,n; 9 int G[N][N],dis[N],mark[N]; 10 int s[N],e[N]; 11 12 void Getmap(){ 13 int a,b,t; 14 n=0; 15 memset(G,Inf,sizeof(G)); 16 for(int i=0;i<T;i++){ 17 scanf("%d%d%d",&a,&b,&t); 18 if(n<max(a,b)) n=max(a,b); 19 G[i][i]=0; 20 if(t<G[a][b]) G[a][b]=G[b][a]=t; 21 } 22 23 for(int i=0;i<S;i++) 24 scanf("%d",&s[i]); 25 for(int i=0;i<D;i++) 26 scanf("%d",&e[i]); 27 28 for(int i=0;i<S;i++)//把初始点之间的距离更新为0 29 for(int j=i+1;j<S;j++) 30 G[s[i]][s[j]]=G[s[j]][s[i]]=0; 31 32 } 33 34 void Dijk(int s){ 35 int mini,p; 36 memset(mark,0,sizeof(mark)); 37 for(int i=1;i<=n;i++) 38 dis[i]=G[s][i]; 39 for(int k=0;k<n;k++){ 40 mini=Inf; 41 for(int i=1;i<=n;i++) 42 if(!mark[i]&&dis[i]<mini){ 43 p=i; 44 mini=dis[i]; 45 } 46 mark[p]=1; 47 for(int i=1;i<=n;i++){ 48 if(dis[i]>dis[p]+G[p][i]) 49 dis[i]=dis[p]+G[p][i]; 50 } 51 } 52 } 53 54 int main(){ 55 while(~scanf("%d%d%d",&T,&S,&D)){ 56 int ans=Inf; 57 Getmap(); 58 for(int i=0;i<S;i++){ 59 Dijk(s[i]); 60 for(int j=0;j<D;j++){ 61 if(dis[e[j]]<ans) ans=dis[e[j]]; 62 } 63 } 64 printf("%d\n",ans); 65 } 66 return 0; 67 }
法二:
1 //设家节点 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define Inf 0x3f3f3f3f 6 #define N 1005 7 using namespace std; 8 int T,S,D,n; 9 int G[N][N],dis[N],mark[N]; 10 int s[N],e[N]; 11 12 void Getmap(){ 13 int a,b,t; 14 n=0; 15 memset(G,Inf,sizeof(G)); 16 for(int i=0;i<T;i++){ 17 scanf("%d%d%d",&a,&b,&t); 18 if(n<max(a,b)) n=max(a,b); 19 if(t<G[a][b]) G[a][b]=G[b][a]=t; 20 } 21 for(int i=0;i<=n;i++) 22 G[i][i]=0; 23 24 for(int i=0;i<S;i++) 25 scanf("%d",&s[i]); 26 for(int i=0;i<D;i++) 27 scanf("%d",&e[i]); 28 29 for(int i=0;i<S;i++)//把家与各初始点间距离设为0 30 G[0][s[i]]=G[s[i]][0]=0; 31 } 32 33 void Dijk(){ 34 int mini,p; 35 memset(mark,0,sizeof(mark)); 36 for(int i=0;i<=n;i++) 37 dis[i]=G[0][i]; 38 for(int k=0;k<=n;k++){ 39 mini=Inf; 40 for(int i=1;i<=n;i++) 41 if(!mark[i]&&dis[i]<mini){ 42 p=i; 43 mini=dis[i]; 44 } 45 mark[p]=1; 46 for(int i=1;i<=n;i++){ 47 if(dis[i]>dis[p]+G[p][i]) 48 dis[i]=dis[p]+G[p][i]; 49 } 50 } 51 } 52 53 int main(){ 54 while(~scanf("%d%d%d",&T,&S,&D)){ 55 int ans=Inf; 56 Getmap(); 57 Dijk(); 58 for(int j=0;j<D;j++) 59 if(dis[e[j]]<ans) ans=dis[e[j]]; 60 printf("%d\n",ans); 61 } 62 return 0; 63 }
以上是关于HDU-2066-一个人的旅行(多源到多源最短路)的主要内容,如果未能解决你的问题,请参考以下文章