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;
}