Codeforces Round #621 (Div. 1 + Div. 2)D(最短路,图)

 1 #define HAVE_STRUCT_TIMESPEC
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 int a[200007];
 5 vector<int>v[200007];
 6 int vis[200007];
 7 int dis[200007];
 8 int vis2[200007];
 9 int dis2[200007];
10 void dijkstra(int x){
11     dis[x]=0;
12     priority_queue<pair<int,int> >pq;
13     pq.push({0,x});
14     while(!pq.empty()){
15         int now=pq.top().second;
16         pq.pop();
17         if(vis[now])
18             continue;
19         vis[now]=1;
20         for(int i=0;i<v[now].size();++i){
21             int t=v[now][i];
22             if(vis[t])
23                 continue;
24             if(dis[now]+1<dis[t]){
25                 dis[t]=dis[now]+1;
26                 pq.push({-dis[t],t});
27             }
28         }
29     }
30 }
31 void dijkstra2(int x){
32     dis2[x]=0;
33     priority_queue<pair<int,int> >pq;
34     pq.push({0,x});
35     while(!pq.empty()){
36         int now=pq.top().second;
37         pq.pop();
38         if(vis2[now])
39             continue;
40         vis2[now]=1;
41         for(int i=0;i<v[now].size();++i){
42             int t=v[now][i];
43             if(vis2[t])
44                 continue;
45             if(dis2[now]+1<dis2[t]){
46                 dis2[t]=dis2[now]+1;
47                 pq.push({-dis2[t],t});
48             }
49         }
50     }
51 }
52 pair<int,int>b[200007];
53 int main(){
54     ios::sync_with_stdio(false);
55     cin.tie(NULL);
56     cout.tie(NULL);
57     int n,m,k;
58     cin>>n>>m>>k;
59     for(int i=1;i<=k;++i)
60         cin>>a[i];
61     for(int i=1;i<=m;++i){
62         int x,y;
63         cin>>x>>y;
64         v[x].push_back(y);
65         v[y].push_back(x);
66     }
67     for(int i=1;i<=n;++i){
68         dis[i]=1e9;
69         dis2[i]=1e9;
70     }
71     dijkstra(1);
72     dijkstra2(n);
73     int ans=0;
74     //在两个点x和y之间连边,如果经过xy这条边的路径成为新的最短路,这条路的长度为min(dis[x]+dis2[y]+1,dis[y]+dis2[x]+1)
75     //移项可得当dis[x]-dis2[x]<=dis[y]-dis2[y]时,这条路长度为dis[x]+dis2[y]+1,所以以dis[x]-dis2[x]大小排序,排在数组前面的点取和1的距离,后面枚举和n的距离
76     for(int i=1;i<=k;++i)
77         b[i]=make_pair(dis[a[i]]-dis2[a[i]],a[i]);//b数组中的点取和1的距离
78     sort(b+1,b+1+k);
79     int temp=dis[b[1].second];
80     for(int i=2;i<=k;++i){
81         ans=max(ans,temp+dis2[b[i].second]+1);//当前点取和n的距离
82         temp=max(temp,dis[b[i].second]);
83     }
84     ans=min(ans,dis[n]);//和最短路作比较,如果最短路更短,那么将不会走其他路
85     cout<<ans<<"\n";
86     return 0;
87 }

猜你喜欢

转载自www.cnblogs.com/ldudxy/p/12326427.html