#Kruskal,可撤销并查集#CF891C Envy

题目

给出一个 \(n\) 个点 \(m\) 条边的无向图,每条边有边权,共 \(Q\) 次询问,

每次给出 \(k_i\) 条边,问这些边能否同时在一棵最小生成树上。


分析

考虑最小生成树选择的边权的种类和数量是固定的,

那么可以按照边权排序,小于该边权的边已经用来构建MST,只需要考虑该边权的边。

按照不同的询问把边加进去看看是否不成环,处理一个询问再把刚刚加入的边撤销。


代码

#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
#define rr register
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)
using namespace std;
const int N=500011; struct rec{int x,y,w;}e[N]; vector<rec>K[N]; char buf[1<<21],*p1,*p2;
int f[N],dep[N],n,m,Q,ans[N],stac[N],tac[N],stad[N*10],tad[N*10],tot,tod;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
bool cmp(rec x,rec y){return x.w<y.w;}
inline signed getf(int u){
	if (f[u]==u) return u;
	rr int U=getf(f[u]);
	if (dep[u]<dep[f[u]]+1){
		stad[++tod]=u,tad[tod]=dep[u];
		dep[u]=dep[f[u]]+1;
	}
	return U;
}
inline bool Merge(int x,int y){
	rr int fa=getf(x),fb=getf(y);
	if (fa==fb) return 0;
	if (dep[fa]>dep[fb]) fa^=fb,fb^=fa,fa^=fb;
	if (dep[fa]==dep[fb])
		stad[++tod]=fb,tad[tod]=dep[fb]++;
	stac[++tot]=fa,tac[tot]=f[fa],f[fa]=fb;
	return 1;
}
signed main(){
	n=iut(),m=iut();
	for (rr int i=1;i<=m;++i)
	    e[i]=(rec){iut(),iut(),iut()};
	for (rr int i=1;i<=n;++i) dep[i]=1,f[i]=i;
	Q=iut();
	for (rr int i=1;i<=Q;++i)
	for (rr int j=iut();j;--j){
		rr int t=iut();
	    K[e[t].w].push_back((rec){e[t].x,e[t].y,i});
	}
	for (rr int i=1;i<=Q;++i) ans[i]=1;
    sort(e+1,e+1+m,cmp);
    for (rr int l=1,r;l<=m;l=r+1){
    	for (r=l;e[r].w==e[l].w;++r); --r;
    	rr int len=K[e[l].w].size();
		tot=tod=0;
    	for (rr int i=0;i<len;++i){
    		rr rec t=K[e[l].w][i];
    		if (!ans[t.w]) continue;
    		if (i>0&&t.w!=K[e[l].w][i-1].w){
    			for (;tot;--tot) f[stac[tot]]=tac[tot];
    			for (;tod;--tod) dep[stad[tod]]=tad[tod];
			}
			ans[t.w]&=Merge(t.x,t.y);
		}
		for (rr int i=l;i<=r;++i) Merge(e[i].x,e[i].y);
	}
	for (rr int i=1;i<=Q;++i) puts(ans[i]?"YES":"NO");
	return 0;
}
posted @ 2021-09-25 10:13  lemondinosaur  阅读(28)  评论(0编辑  收藏  举报