CF2060E Graph Composition
这道题教会了我并查集是可以动态删改的,关键在于判断其是否是连通分量的代表
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL t,n,m1,m2,ans,a[500005],b[500005],fag[500005],faf[500005],hg[500005],hf[500005],cnt1,cnt2;
LL findf(LL x){
if(faf[x]==x) return x;
return faf[x]=findf(faf[x]);
}
LL findg(LL x){
if(fag[x]==x) return x;
return fag[x]=findg(fag[x]);
}
int main(){
cin>>t;
while(t--){
cin>>n>>m1>>m2;
ans=cnt1=cnt2=0;
for(int i=1;i<=n;i++){
faf[i]=fag[i]=i;
hf[i]=hg[i]=0;
}
for(int i=1;i<=m1;i++){
cin>>a[i]>>b[i];
}
for(int x,y,i=1;i<=m2;i++){
cin>>x>>y;
fag[findg(x)]=findg(y);//建立并查集
}
for(int i=1;i<=n;i++){
if(!hg[findg(i)]){
hg[findg(i)]=1;
cnt1++; //处理标记
}
}
for(int i=1;i<=m1;i++){
if(fag[a[i]]==fag[b[i]]){
faf[findf(a[i])]=findf(b[i]); //需要加的边
}else ans++;
}
for(int i=1;i<=n;i++){
if(!hf[findf(i)]){
hf[findf(i)]=1; //需要删的边
cnt2++;
}
}
cout<<ans+cnt2-cnt1<<endl; //本来就有的边不需要操作
}
return 0;
}

浙公网安备 33010602011771号