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

posted @ 2026-02-02 21:41  曾翎一  阅读(1)  评论(0)    收藏  举报