总结
添加一条边,让最短路最大化,肯定跑两次spfa,dis1[i]+1+dis2[j],但是k∈2e5,O(n2)枚举是肯定不可取的,只能降低时间复杂度,要么nlogn,要么n。
因为我们要保证max( dis1[i]+1+dis2[j] ),那么就要保证dis[i]到dis[j]距离最小,这样添加边,才能让最短路损失的最小
后面,我们也看一下别人的做法,是按照dis1[i]-dis2[i]的差值排序的。
const int N=2e5+5;
vector<int>G[N];
int dis1[N],dis2[N];
bool vis[N];
void spfa(int dis[],int x)
{
memset(vis,0);
queue<int>que;
que.push(x);
vis[x]=true;
while(!que.empty())
{
int pos=que.front();
que.pop();
for(auto it:G[pos])
{
if(vis[it])
continue;
dis[it]=dis[pos]+1;
que.push(it);
vis[it]=true;
}
}
}
struct node
{
int pos,value;
bool operator<(const node &b)const
{
return value<b.value;
}
};
signed main()
{
IOS;
int n,m,k;
cin>>n>>m>>k;
vector<int>a(k);
for(auto &it:a)
cin>>it;
while(m--)
{
int x,y;
cin>>x>>y;
G[x].pb(y);
G[y].pb(x);
}
spfa(dis1,1);
spfa(dis2,n);
vector<node>vec;
for(auto it:a)
{
vec.pb( {it,dis1[it]} );
}
sort(all(vec));
int len=vec.size();
int ans=0;
for(int i=1;i<len;i++)
{
int temp=dis1[n];
int x=vec[i-1].pos,y=vec[i].pos;
temp=min(temp,dis1[x]+dis2[y]+1);
temp=min(temp,dis1[y]+dis2[x]+1);
ans=max(ans,temp);
}
cout<<ans<<endl;
return 0;
}