Codeforces - Cow and Fields

题目链接:Codeforces - Cow and Fields


我们先正反两次bfs,求出点1到所有点的最短路和点n到所有点的最短路。

然后对于k个关键点,我们要使得 min(d1[i]+1+d2[j] , d1[j]+1+d2[i]) 最大。

所以问题就转变为求这个的最大值。

我们按照 d1[i] - d2[i] 从大到小排序。

然后从前往后枚举,当我们枚举到 i 时,保证了前面的是更大的那一对,所以我们就用最小值更新即可。

然后维护一个最大的d2,保证转移一定是合法的。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10,M=N<<1;
int n,m,k,a[N],p[N],flag,d[N],d1[N],vis[N],res;
int head[N],nex[M],to[M],tot;
inline void ade(int a,int b){to[++tot]=b; nex[tot]=head[a]; head[a]=tot;}
inline void add(int a,int b){ade(a,b);	ade(b,a);}
int cmp(int a,int b){return d[a]-d1[a]>d[b]-d1[b];}
void bfs(int s,int *d){
	queue<int> q;	d[s]=0; q.push(s);
	while(q.size()){
		int u=q.front();	q.pop();
		for(int i=head[u];i;i=nex[i])	if(d[to[i]]==-1){
			d[to[i]]=d[u]+1;	q.push(to[i]);
		}
	}
}
signed main(){
	cin>>n>>m>>k;
	for(int i=1;i<=k;i++)	scanf("%d",&a[i]);
	for(int i=1,x,y;i<=m;i++)	scanf("%d %d",&x,&y),add(x,y);
	memset(d,-1,sizeof d),memset(d1,-1,sizeof d1);
	bfs(1,d);	bfs(n,d1);
	sort(a+1,a+1+k,cmp);	int mx=-1e9;
	for(int i=1;i<=k;i++)	res=max(res,d[a[i]]+1+mx),mx=max(mx,d1[a[i]]);
	cout<<min(d[n],res);
	return 0;
}
发布了604 篇原创文章 · 获赞 242 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104372861