【图论】CF685E Travelling Through the Snow Queen's Kingdom
我们可以发现 \(s->t\) 这条路径所经过的边的编号单增(且每条边的边号都是大于等于 \(l\)),假如不单增那么分界点后的边都不通。
那么,题目中的走一条边花费 1 就是废的。
对于一个询问,我们只需要把编号大于等于 \(l\) 的拉出去跑最短路即可。
考虑在线过不去,有点 图函数 的意思。
离线询问,从大编号到小编号加入边,询问按 \(l\) 降序排。
考虑加入这条边对最短路的影响。
首先,这条边所经过的时间一定是当前全局最小的。那么一定是 \(from\to to\to i\) 或 \(to\to from \to j\)的形式(根据单增结论),考虑类 floyd 松弛即可。
需要注意的是,松弛的起点都必须是 \(from \ or \ to\),能保证一定经过 \(from\to to\)
途中绿色和蓝色即为路径,保证一定经过新边。
#include <bits/stdc++.h>
using namespace std;
int rd() {
int f=1,sum=0; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
return sum*f;
}
void pr(int x) {
int f=1,tot=0; static int st[30];
if(x<0) x=-x,f=-1;
while(x) st[++tot]=x%10,x/=10;
if(!tot) putchar('0');
else for(int i=tot;i>=1;i--) putchar(st[i]+'0');
}
#define N 1005
#define M (int)(2e5+5)
struct edge {
int l,r,s,t,id;
}Q[M];
bool ans[M];
int fr[M],to[M];
int n,m,q,f[N][N];
bool cmp(edge x,edge y) {
return x.l>y.l;
}
int main() {
n=rd(); m=rd(); q=rd();
for(int i=1;i<=m;i++) fr[i]=rd(),to[i]=rd();
for(int i=1;i<=q;i++) {
Q[i].l=rd(); Q[i].r=rd(); Q[i].s=rd(); Q[i].t=rd(); Q[i].id=i;
}
sort(Q+1,Q+1+q,cmp); int nw=1;
memset(f,0x3f,sizeof(f));
for(int i=m;i>=1;i--) {
f[fr[i]][to[i]]=f[to[i]][fr[i]]=i;
for(int j=1;j<=n;j++) {
f[to[i]][j]=min(f[to[i]][j],f[fr[i]][j]);
f[fr[i]][j]=min(f[fr[i]][j],f[to[i]][j]);
}
while(nw<=q&&Q[nw].l==i) {
if(f[Q[nw].s][Q[nw].t]<=Q[nw].r) ans[Q[nw].id]=1;
++nw;
}
}
for(int i=1;i<=q;i++) {
if(ans[i]) printf("Yes\n");
else printf("No\n");
}
return 0;
}