HDU2066dijkstra模板题

 

问题描述:

 

题目描述:
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,便是可以一劳永逸。
 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 }

 

 
posted @ 2020-01-20 10:55  remarkableboy  阅读(298)  评论(0编辑  收藏  举报