2020牛客多校(三) G Operating on a Graph(并查集+stl)

用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;
    }
}
View Code

 

posted @ 2020-07-19 10:19  朝暮不思  阅读(226)  评论(0编辑  收藏  举报