D. Cow and Fields
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Bessie is out grazing on the farm, which consists of n fields connected by m bidirectional roads. She is currently at field 1, and will return to her home at field n at the end of the day.
The Cowfederation of Barns has ordered Farmer John to install one extra bidirectional road. The farm has k special fields and he has decided to install the road between two different special fields. He may add the road between two special fields that already had a road directly connecting them.
After the road is added, Bessie will return home on the shortest path from field 1 to field n. Since Bessie needs more exercise, Farmer John must maximize the length of this shortest path. Help him!
Input
The first line contains integers n, m, and k (2≤n≤2⋅105, n−1≤m≤2⋅105, 2≤k≤n) — the number of fields on the farm, the number of roads, and the number of special fields.
The second line contains k integers a1,a2,…,ak (1≤ai≤n) — the special fields. All ai are distinct.
The i-th of the following m lines contains integers xi and yi (1≤xi,yi≤n, xi≠yi), representing a bidirectional road between fields xi and yi.
It is guaranteed that one can reach any field from every other field. It is also guaranteed that for any pair of fields there is at most one road connecting them.
Output
Output one integer, the maximum possible length of the shortest path from field 1 to n after Farmer John installs one road optimally.
Examples
inputCopy
5 5 3
1 3 5
1 2
2 3
3 4
3 5
2 4
outputCopy
3
inputCopy
5 4 2
2 4
1 2
2 3
3 4
4 5
outputCopy
3
Note
The graph for the first example is shown below. The special fields are denoted by red. It is optimal for Farmer John to add a road between fields 3 and 5, and the resulting shortest path from 1 to 5 is length 3.
The graph for the second example is shown below. Farmer John must add a road between fields 2 and 4, and the resulting shortest path from 1 to 5 is length 3.
题意:有n个点,m条无向边,k个关键点,现在让你在关键点之中选择两个点 让他们连接一条无向边,求1-n的最短路的最大值为多少,其中图中的边权都是1
思路:
第一步:首先因为是边权为1的图,我们可以想到一种比较暴力的做法
就是
dis[i][0] 表示从点1到点i的最短距离
dis[j][0]表示从点j到点n的最短距离
这样的话 可以用O(k^2) 暴力枚举 取dis[i][0]+dis[j][1]的最大值
显然复杂度是不可行的,所以下一步考虑优化
第二步:
我们假设取关键点为i和j 那么有两种走法
1->i->j->n 或者1->j->i->n
我们假设前者的走法的值更小 也就是 dis[i][0]+dis[j][1]+1<dis[j][0]+dis[i][1]+1‘
上式移项可得 dis[i][0]-dis[i][1]<dis[j][0]-dis[j][1]
这个式子什么意思呢?
就是说 对于i和j这两个关键点 我先走i再走j这样的走法的值更小 也就是满足1到n是最短路的条件
这样的话我们对于k个关键点 按照dis[i][0]-dis[i][1]升序排序
这样一来 就满足了怎么走都是最短路了
然后我们去维护前面的1到i的最大值 ma=max(ma,dis[a[i]][0])
这样的话最短路的最大值就是枚举j ans=max(ans,ma+dis[a[j]][1]+1)
注意最后记得跟原图的1的n的最短路进行比较
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define me(a,x) memset(a,x,sizeof a)
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define all(x) (x).begin(), (x).end()
#define pb(a) push_back(a)
#define paii pair<int,int>
#define pali pair<ll,int>
#define pail pair<int,ll>
#define pall pair<ll,ll>
#define fi first
#define se second
int a[200005];//关键点记录
vector<int> v[200005];//存图
int dis[200005][2];///存值
int n,m,k;
void bfs(int x,int k){///计算最短路
queue<int> q;
vector<bool> vis(n+1,0);///标记是否走过
vis[x]=1;
dis[x][k]=0;
q.push(x);
while(!q.empty()){
int now=q.front();
q.pop();
for(auto it:v[now]){
if(!vis[it] && dis[it][k]>dis[now][k]+1){
vis[it]=1;
dis[it][k]=dis[now][k]+1;
q.push(it);
}
}
}
}
int main()
{
cin>>n>>m>>k;
rep(i,0,k) cin>>a[i];
rep(i,0,m){
int x,y;
cin>>x>>y;
v[x].pb(y);
v[y].pb(x);
}
me(dis,0x3f);
bfs(1,0);
bfs(n,1);
sort(a,a+k,[](int a,int b){///排序
return dis[a][0]-dis[b][0]<dis[a][1]-dis[b][1];
});
int ma=dis[a[0]][0],ans=0;
rep(i,1,k){//枚举点
ans=max(ans,ma+dis[a[i]][1]+1);
ma=max(ma,dis[a[i]][0]);
}
cout<<min(ans,dis[n][0])<<endl;
return 0;
}