1. 程式人生 > >Codeforces 920 E Connected Components?

Codeforces 920 E Connected Components?

都是 class nss mos rom ssl ati middle bfs

Discription

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


我們發現對於N個點的完全圖來說,刪去M條邊的影響是有限的(因為N和M最大都是2*10^5)。
所以可以猜測的是不會有很多聯通塊。那麽就可以暴力BFS一下,用一個鏈表來維護當前還沒有被放入聯通塊的節點。
當我們從一個節點擴展的時候,就在鏈表裏找它所能到達的點,然後把它們從鏈表中刪去,假如BFS的隊列中。


我們在鏈表中掃到一個元素還不刪除的次數之和最多是2*M,因為只有和當前點有連邊的鏈表中的點才不會被刪除。
這樣就保證了時間復雜度,也就是每個點最多進一次隊列,鏈表中的所有點被掃到的次數之和<=2*M+N。

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<map>
#define ll long long
#define maxn 200005
using namespace std;
map<int,int> mmp[maxn];
int ans[maxn],tot=0,n,m;
int hd,ne[maxn];

inline void solve(int tmp){
	queue<int> q;
	ans[tmp]=0;
    int x,now,pre;
		
	q.push(hd),hd=ne[hd];
	while(!q.empty()){
		x=q.front(),q.pop(),ans[tmp]++;
		
		for(now=hd,pre=0;now;now=ne[now])
			if(!mmp[x][now]){
				q.push(now);
				if(hd==now) hd=ne[hd];
				ne[pre]=ne[now];
			}
			else pre=now;
	}
}

int main(){
	int uu,vv;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&uu,&vv);
		mmp[uu][vv]=mmp[vv][uu]=1;
	}
	
	for(int i=1;i<=n;i++) ne[i]=hd,hd=i;
	
	while(hd) solve(++tot);
	
	printf("%d\n",tot);
	sort(ans+1,ans+tot+1);
	for(int i=1;i<=tot;i++) printf("%d ",ans[i]);
	puts("");
	
	return 0; 
}

  

 

Codeforces 920 E Connected Components?