天天看点

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