CodeForces 920 E.Connected Components? (set+bfs)

题意:

给n和m,n表示n个点
然后给m个二元组,每个二元组ab表示ab之间没有边,其他都有边
求图中连通块的数量和每个连桶块的大小,将大小从小到大输出

即求补图的连通块数量

思路:

计算方法和cf1243d一样:cf1243d题解

code:

#include<bits/stdc++.h>
using namespace std;
const int maxm=2e5+5;
set<int>g[maxm];//存图(非补图)
set<int>s;//存没搜过的点
int mark[maxm];//标记搜过的点
vector<int>ans;//存连通块大小
int n,m;
void bfs(int st){
    int cnt=0;
    queue<int>q;
    q.push(st);
    s.erase(st);//搜过的删掉
    while(!q.empty()){
        int x=q.front();
        q.pop();
        if(mark[x])continue;
        cnt++;
        mark[x]=1;
        set<int>::iterator it;
        for(it=s.begin();it!=s.end();){
            int v=*it;
            it++;
            if(g[x].find(v)==g[x].end()){//如果能找到说明x到v右边,不能走,反之没搜到可以走
                q.push(v);
                s.erase(v);
            }
        }
    }
    ans.push_back(cnt);
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        s.insert(i);
    }
    for(int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        g[a].insert(b);
        g[b].insert(a);
    }
    for(int i=1;i<=n;i++){
        if(!mark[i]){
            bfs(i);
        }
    }
    cout<<ans.size()<<endl;
    sort(ans.begin(),ans.end());//题目要求从小到大
    for(int i=0;i<(int)ans.size();i++){
        cout<<ans[i]<<' ';
    }
    cout<<endl;
    return 0;
}
发布了364 篇原创文章 · 获赞 26 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/103207598
920
今日推荐