题意:给你一个图补图的边问原图有多少个组成部分,以及每个组成部分的大小
题解:用set保存还没遍历的点每次从一个没被遍历的点出发做一次bfs统计个数就可以了。
#include<bits/stdc++.h> #include<set> #include<iostream> #include<string> #include<cstring> #include<algorithm> #define pb push_back #define ll long long #define PI 3.14159265 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define eps 1e-7 typedef unsigned long long ull; const int mod=1e9+7; const int maxn=3e5+5; const int root=1e6+7; using namespace std; int t,cnt,n,m; bool vis[maxn]; vector<int>g[maxn],ans; set<int> s1,s2; void init() { for(int i=1;i<=n;i++) { s1.insert(i); } } void bfs(int s) { queue<int>q; s1.erase(s);s2.clear(); vis[s]=true;cnt++; q.push(s); set<int>::iterator it; while(!q.empty()) { int s=q.front(); q.pop(); for(int i=0;i<g[s].size();i++) { s1.erase(g[s][i]); s2.insert(g[s][i]); } for(it=s1.begin();it!=s1.end();it++) { if(!vis[*it]) { cnt++;vis[*it]=true;q.push(*it); } } s1.swap(s2); s2.clear(); } return; } int main() { scanf("%d %d",&n,&m); init(); for(int i=0;i<m;i++) { int a,b; scanf("%d %d",&a,&b); g[a].pb(b); g[b].pb(a); } for(int i=1;i<=n;i++) { if(!vis[i]) { cnt=0; bfs(i); ans.pb(cnt); } } sort(ans.begin(),ans.end()); printf("%d\n",ans.size()); for(int i=0;i<ans.size();i++) { printf("%d ",ans[i]); } printf("\n"); return 0; }