You are given an undirected graph consisting of n vertices and edges. Instead of giving you the edges that exist in the graph, we give you m unordered pairs (x, y) such that there is no edge between x and y, and if some pair of vertices is not listed in the input, then there is an edge between these vertices.
You have to find the number of connected components in the graph and the size of each component. A connected component is a set of vertices X such that for every two vertices from this set there exists at least one path in the graph connecting these vertices, but adding any other vertex to X violates this rule.
Input
The first line contains two integers n and m (1 ≤ n ≤ 200000, ).
Then m lines follow, each containing a pair of integers x and y (1 ≤ x, y ≤ n, x ≠ y) denoting that there is no edge between x and y. Each pair is listed at most once; (x, y) and (y, x) are considered the same (so they are never listed in the same test). If some pair of vertices is not listed in the input, then there exists an edge between those vertices.
Output
Firstly print k — the number of connected components in this graph.
Then print k integers — the sizes of components. You should output these integers in non-descending order.
Example
input
5 5
1 2
3 4
3 2
4 2
2 5
output
2
1 4
题目是给你一个图,让你求这个图的反图的联通块个数和大小,这道题我们当然不能耿直的直接建一个反图,因为这个图是稀疏图,那么他的反图肯定是稠密图。我们可以遍历每一个点,对于每一个点,找到与他不相邻的且以前没有被访问过的点,加入队列,然后bfs,与他说明两点之间不相连,说明原图之间肯定相连,把他加入后说明这两个点肯定在一个联通块里,被访问过就说明已经被加到一个联通块里了,但这里我们还是O(n^2)的复杂度,我们这时可以用链表优化bfs,因为每个点要找到没有与之相邻的点,所以我们可以把所有点加入到链表中,在使用过这个点之后在链表中删去,这样复杂度就降到了O(n+m)
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
vector<int>E[maxn];
vector<int>ans;
bool vis[maxn],book[maxn];
list<int>lists;
int bfs(int x) {
queue<int>Q;
Q.push(x);
int num=0;
while(!Q.empty()) {
int now=Q.front();
Q.pop();
if(vis[now]) continue;
vis[now]=true,num++;
for(auto &it:E[now]) book[it]=true;
for(auto it=lists.begin();it!=lists.end();it++) {
int v=*it;
if(!book[v]) {
Q.push(v);
lists.erase(it);
}
}
for(auto &it:E[now]) book[it]=false;
}
return num;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n,m,x,y;
cin>>n>>m;
for(int i=1;i<=n;i++)lists.push_back(i);
for(int i=1;i<=m;i++) {
cin>>x>>y;
E[x].push_back(y);
E[y].push_back(x);
}
for(int i=1;i<=n;i++) {
if(!vis[i]) ans.push_back(bfs(i));
}
sort(ans.begin(),ans.end());
cout<<ans.size()<<endl;
for(auto it:ans) cout<<it<<" ";
return 0;
}