AcWing 3797. 最大化最短路(图论)
Posted CCSU_Cola
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 3797. 最大化最短路(图论)相关的知识,希望对你有一定的参考价值。
题意:在k个特殊点之间选两个点,在之间连一条边,使得1-n的最短路最大。每条边的路的长度都为1。
思路:从起点和终点出发分别跑一次bfs,求出dist1数组和distn数组,可以知道在a,b两点之间连一条边,最短路可能会不变,也有可能变成dist1[a]+distn[b]+1或者distn[a]+dist1[b]+1,若发生改变,那么最短路的最大值就是min(dist1[a]+distn[b]+1,distn[a]+dist1[b]+1),假设dist1[a]+distn[b]+1小于等于distn[a]+dist1[b]+1会得到dist1[a]-distn[a]<=dist1[b]-distn[b]那么我们只需要保证dist1[a]-distn[a]<=dist1[b]-distn[b]就可以保证最小值为dist1[a]+distn[b]+1。将k个特殊点按照dist1[i]-distn[i]排序,就可保证后面的点的dist1[i]-distn[i]大于前面的,但是为了使得dist1[a]+distn[b]+1最大,我们需要维护一个前缀的dist1[a]的最大值,然后与当前点的distn相加再加上1,即为dist1[a]+distn[b]+1,然后再每一个答案取一个max即可。还需和原来的dist1[n]取一个最小值,因为可能选取的两个点对最短路不造成影响。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
int a[maxn],h[maxn];
int n,m,k,idx;
struct tt
int x,to;
;
tt e[maxn<<1];
int dist1[maxn],dist2[maxn];
void add(int a,int b)
e[idx].x=b,e[idx].to=h[a],h[a]=idx++;
void bfs(int x,int dist[])
queue<int>q;
q.push(x);
for(int i=1;i<=n;i++)
dist[i]=1e9;
dist[x]=0;
while(!q.empty())
int t=q.front();
q.pop();
for(int i=h[t];i!=-1;i=e[i].to)
int j=e[i].x;
if(dist[j]>dist[t]+1)
dist[j]=dist[t]+1;
q.push(j);
bool cmp(int a,int b)
return dist1[a]-dist2[a]<dist1[b]-dist2[b];
int main()
memset(h,-1,sizeof h);
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
scanf("%d",&a[i]);
int x,y;
for(int i=1;i<=m;i++)
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
bfs(1,dist1);
bfs(n,dist2);
sort(a+1, a+k+1,cmp);
int res = 0;
x = dist1[a[1]];
for (int i=2;i<=k;i++)
int t=a[i];
res=max(res, dist2[t]+x+1);
x=max(x, dist1[t]);//更新当前点之前的dist1的最大值
printf("%d\\n",min(res,dist1[n]));//与本身的最短路取min
以上是关于AcWing 3797. 最大化最短路(图论)的主要内容,如果未能解决你的问题,请参考以下文章