CF685E Travelling Through the Snow Queen's Kingdom 题解

传送门

一道 CF28002000。

考虑离线,倒着加入每条边。

\(f_{i,j}\) 表示点 \(i\) 为起点,点 \(j\) 为终点时路径上最后一条边的编号的最小值。由于每次加入的边 \((x,y)\) 的编号是当前边集内最小的,只需要更新所有的 \(f_{x,i}\)\(f_{y,i}\),更新显然。单次更新的时间复杂度是 \(O(n)\),每个询问是 \(O(1)\) 判断的,总时间复杂度 \(O(mn+q)\)

参考代码:

#include<bits/stdc++.h>
#define mxn 200003
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
struct node{
	int x,y;
}a[mxn];
struct ask{
	int r,s,t,i;
};
int n,m,q,f[1002][1002];
bool ans[mxn];
vector<ask>d[mxn];
signed main(){
	scanf("%d%d%d",&n,&m,&q);
	rep(i,1,m)scanf("%d%d",&a[i].x,&a[i].y);
	memset(f,0x3f,sizeof(f)); 
	int l,r,s,t;
	rep(i,1,q){
		scanf("%d%d%d%d",&l,&r,&s,&t);
		d[l].pb({r,s,t,i});
	}
	drep(i,m,1){
		int x=a[i].x,y=a[i].y;
		f[x][y]=min(f[x][y],i);
		rep(j,1,n)f[x][j]=min(f[x][j],f[y][j]);
		f[y][x]=min(f[y][x],i);
		rep(j,1,n)f[y][j]=min(f[y][j],f[x][j]);
		for(ask j:d[i])ans[j.i]=f[j.s][j.t]<=j.r;
	}
	rep(i,1,q)puts(ans[i]?"Yes":"No");
	return 0;
}
posted @ 2023-11-27 22:11  zifanwang  阅读(4)  评论(0编辑  收藏  举报  来源