天天看點

cf920e(連結清單優化bfs)

求反圖聯通塊,由于反圖邊太多,直接暴力行不通。。。然後陷入沉思。。

标解算是比較少見的算法了吧。。

枚舉每個點,和平常一樣bfs找聯通的點,不一樣的是在找點時要先标記不連通的之後再找。。

然後這樣複雜度是 O(n^2)還是不行。。

是以用連結清單優化,儲存目前還沒有找到聯通塊的點,由于原圖邊非常少,聯通塊不會很多,是以基本上找到第兩三個聯通塊連結清單中的點就剩不了多少了。。

這裡的連結清單嘗試用了一下list容器。。寫起來比較友善。。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<list>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define eps 1e-8
#define inf 1e9
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define ls T[i<<1]
#define rs T[i<<1|1]
#define op T[i]
#define mid (x+y>>1)
#define NM 1000005
#define nm 400005
#define pi 3.141592653
using namespace std;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}






int n,m,_x,_y,ans[NM],cnt;
bool c[NM],v[NM];
queue<int >q;
struct edge{int t;edge*next;}e[nm],*h[NM],*o=e;
void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}

list<int >b;
int bfs(int x){
    int s=0;q.push(x);v[x]++;
    while(!q.empty()){
        int t=q.front();q.pop();
        link(t)c[j->t]=true;
        for(auto it=b.begin();it!=b.end();)
            if(!c[*it])q.push(*it),v[*it]++,s++,b.erase(it++);
            else it++;
        link(t)c[j->t]=false;
    }
    return s;
}


int main(){
    n=read();m=read();
    inc(i,1,n)b.push_back(i);
    inc(i,1,m){_x=read();_y=read();add(_x,_y);add(_y,_x);}
    inc(i,1,n)if(!v[i])ans[++cnt]=bfs(i);
    sort(ans+1,ans+1+cnt);
    printf("%d\n",cnt);
    inc(i,1,cnt-1)printf("%d ",ans[i]);printf("%d\n",ans[cnt]);
    return 0;
}      

E. Connected Components?

time limit per test

memory limit per test

input

output

You are given an undirected graph consisting of n vertices and

cf920e(連結清單優化bfs)

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

Input

The first line contains two integers n and m (1 ≤ n ≤ 200000,

cf920e(連結清單優化bfs)

).

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

Output

Firstly print k

Then print k

Example

Input

5 51 23 4

3 2

4 2

2 5

Output