【图论】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;
}
posted @ 2022-02-08 18:02  FxorG  阅读(8)  评论(0编辑  收藏  举报