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