Cow and Fields
Solution
分别从1、n广搜,可以得到每个点在广搜树中的层数:d[i],dn[i],考虑加一条边(x,y),则新出现的路中,可能为最短路的是:min(d[x]+dn[y]-1,d[y]+dn[x]-1)。
又由\(d[x]+dn[y]-1 < d[y]+dn[x]-1\)得\(d[x]-dn[x] < d[y]-dn[y]\) 那么按d[i]-dn[i]排序,之后,找到最大的 \(dn[i]+max_{j< i}(d[j])\),再与d[n]比较。
复杂度O(n*logn+m)
Code
#include<bits/stdc++.h>
using namespace std;
int n,m,k,f[200005],d[200005],sp[200005],dn[200005],vis[200005];
queue<int> q;
vector<int> head[200005],rs;
const int com1(const int &a,const int &b)
{
return d[a]-dn[a]<d[b]-dn[b];
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
{
int a;
scanf("%d",&a);
sp[i]=a;
}
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
head[a].push_back(b);
head[b].push_back(a);
}
d[1]=1;
q.push(1);
while(!q.empty())
{
int dg=q.front();
q.pop();
for(int i=0;i<head[dg].size();i++)
{
int v=head[dg][i];
if(!d[v])
{
d[v]=d[dg]+1;
f[v]=dg;
q.push(v);
}
}
}
dn[n]=1;
q.push(n);
while(!q.empty())
{
int dg=q.front();
q.pop();
for(int i=0;i<head[dg].size();i++)
{
int v=head[dg][i];
if(!dn[v])
{
dn[v]=dn[dg]+1;
q.push(v);
}
}
}
sort(sp+1,sp+1+k,com1);
int ans=0,mx=d[sp[1]];
for(int i=2;i<=k;i++)
{
ans=max(ans,mx+dn[sp[i]]);
mx=max(mx,d[sp[i]]);
}
printf("%d\n",min(ans-1,d[n]-1));
}