G-Operating on a Graph 2020牛客多校第3场

https://ac.nowcoder.com/acm/contest/5668/G

启发式合并,然后记录一下头指针,合并枚举元素的时候顺便连一下边

#include<bits/stdc++.h>
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd(int &x){
    char c=nc(),f=1;
    for(;(c<'0'||c>'9')&&c!=EOF;c=nc()) if(c=='-') f=-1;
    if(c==EOF) return EOF;
    for(x=0;c>='0'&&c<='9';c=nc()) x=x*10+c-'0';
    x*=f;
    return 1;
}
 
 
const int N=1e6;
struct P{
    int a,b;
};
vector<P>B[N];
int fa[N],ha[N],h;
int f(int x){
    if(fa[x]==x) return x;
    int k=f(fa[x]);
    fa[x]=k;
    return k;
}
 
int main(){
    int i,j,t,n,m,x,a,b;
    //scanf("%d",&t);
    rd(t);
    while(t--){
        //scanf("%d%d",&n,&m);
        rd(n);rd(m);
        for(i=0;i<n;i++){
             fa[i]=i;
             B[i].clear();
        }
        while(m--){
             rd(a);rd(b);
            // scanf("%d%d",&a,&b);
             B[a].push_back(P{a,b});
             B[b].push_back(P{a,b});
        }
 
        rd(m);
        //scanf("%d",&m);
        while(m--){
            //scanf("%d",&x);
            rd(x);
            if(f(x)!=x) continue;
 
            h=0;
            for(i=0;i<B[x].size();i++){
                a=f(B[x][i].a);
                b=f(B[x][i].b);
                if(a!=x) ha[++h]=a;
                if(b!=x) ha[++h]=b;
            }
            B[x].clear();
            sort(ha+1,ha+1+h);
            h=unique(ha+1,ha+1+h)-ha-1;
            for(i=1;i<=h;i++){
                a=ha[i];
                if(B[a].size()>B[x].size()) swap(B[a],B[x]);
                for(j=0;j<B[a].size();j++) B[x].push_back(B[a][j]);
                fa[a]=x;
                B[a].clear();
            }
        }
         
         
 
        for(i=0;i<n;i++) printf("%d ",f(i));
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/107431401
今日推荐