用list维护每个节点能往外的信息,list有一个splice函数可以在list后面合并新的list,这样操作方便,之后其实就是暴力并查集+bfs,注意去重。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; const int N=8e5+10; const int mod=1e9+7; list<int> li[N]; vector<int> num[N]; int p[N]; int n,m; int vis[N]; void init(){ int i; for(i=0;i<n+5;i++){ li[i].clear(); p[i]=i; num[i].clear(); vis[i]=0; } for(i=0;i<n+5;i++) li[i].push_back(i); } int find(int x){ if(x!=p[x]){ p[x]=find(p[x]); } return p[x]; } void bfs(int u){ if(find(u)!=u) return ; int i; int sz=li[u].size(); for(i=0;i<sz;i++){ auto x=li[u].front(); for(auto t:num[x]){ int pa=find(t); int pb=find(x);//假如已经在group内就不用合并 if(pa!=pb){ p[pa]=pb; li[pb].splice(li[pb].end(),li[pa]);//STL } if(vis[t])//如果存在重复指向这个点的,就跳过 continue; vis[t]=1; //li[u].push_back(t); } li[u].pop_front(); } } int main(){ ios::sync_with_stdio(false); int t; cin>>t; while(t--){ cin>>n>>m; init(); while(m--){ int a,b; cin>>a>>b; num[a].push_back(b); num[b].push_back(a); } int q; cin>>q; while(q--){ int pos; cin>>pos; bfs(pos); } for(int i=0;i<n;i++) cout<<find(i)<<" "; cout<<endl; } }