HDU2066dijkstra模板题
问题描述:
题目描述:
Problem Description
虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
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的n^3logn的想法,但那样会tle,这道题有一个比较巧妙的点,如果就直接把他家看成起点
到相邻城市的权为0,便是可以一劳永逸。
输入数据有多组,每组的第一行是三个整数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的n^3logn的想法,但那样会tle,这道题有一个比较巧妙的点,如果就直接把他家看成起点
到相邻城市的权为0,便是可以一劳永逸。
1 #include<bits/stdc++.h> 2 #define N 2050 3 using namespace std; 4 priority_queue<pair<int,int> >q; 5 int cnt,head[N<<1]; 6 long long wt[N<<1],vis[N],a[N],b[N]; 7 int n,m,p; 8 int dp[N][N]; 9 long long temp; 10 struct node 11 { 12 int to; 13 int next; 14 int w; 15 } e[100000]; 16 inline void add(int x,int y,int w)//链式向前星存图 17 { 18 e[++cnt].to=y; 19 e[cnt].w=w; 20 e[cnt].next=head[x]; 21 head[x]=cnt; 22 } 23 inline void dijkstra(int k)//dijkstra模板 24 { 25 for(int i=1;i<=N;i++) 26 wt[i]=999999999; 27 wt[k]=0; 28 q.push(make_pair(0,k)); 29 while(!q.empty()){ 30 int x=q.top().second; 31 q.pop(); 32 if(vis[x]) 33 continue; 34 vis[x]=1; 35 for(int i=head[x];i;i=e[i].next) 36 { 37 int y=e[i].to; 38 int z=e[i].w; 39 if(wt[y]>wt[x]+z) 40 {wt[y]=wt[x]+z; 41 q.push(make_pair(-wt[y],y)); 42 } 43 } 44 } 45 } 46 int main() 47 { 48 while(scanf("%d%d%d",&n,&m,&p)!=EOF) 49 { 50 temp=999999999; 51 for(int i=1; i<=n; i++) 52 { 53 54 int x,y,z; 55 scanf("%d%d%d",&x,&y,&z); 56 if(dp[x][y]==0) 57 { 58 add(x,y,z); 59 add(y,x,z); 60 dp[x][y]=z; 61 } 62 else 63 { 64 z=min(z,dp[x][y]); 65 add(x,y,z); 66 add(y,x,z); 67 } 68 }//存最小权重边 69 for(register int i=0; i<m; i++) 70 { 71 int x; 72 scanf("%d",&x); 73 a[i]=x; 74 add(0,x,0);//到相邻城市权为0 75 } 76 for(register int i=0; i<p; i++) 77 { 78 int x; 79 scanf("%d",&x); 80 b[i]=x; 81 } 82 dijkstra(0); 83 for(register int j=0; j<p; j++) 84 { 85 temp=min(temp,wt[b[j]]);//更新最小值 86 } 87 printf("%d\n",temp); 88 memset(dp,0,sizeof(dp)); 89 memset(head,0,sizeof(head)); 90 memset(a,0,sizeof(a)); 91 memset(b,0,sizeof(b)); 92 memset(vis,0,sizeof(vis)); 93 } 94 return 0; 95 }