Problem : poi 2007 biu
Solution : BFS + 链表优化
#include<map>
#include<queue>
#include<stack>
#include<utility>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<iostream>
#include<algorithm>
#define Mp(x,y) std::make_pair(x,y)
#define Pre first
#define Sur second
const int MAXN = 1e5+5, MAXM = 2e6+5;
typedef std::pair<int,int> LinkType;
int n, m;
struct Edge{int v,next;Edge(int v = 0,int next = 0):v(v),next(next){}};
int el, head[MAXN];
Edge edge[MAXM<<1] = {0};
int lh = 0;
LinkType link[MAXN];
int line[MAXN] = {0}, f, r;
bool hash[MAXN] = {false};
int ans = 0, size[MAXN] = {0};
void NewEdge(int u,int v){++el; edge[el] = Edge(v,head[u]); head[u] = el;}
void BuildLink()
{
for(int i = 1; i < n; i++)
link[i].Sur = i+1, link[i+1].Pre = i;
lh = 1;
}
void LinkDel(int x)
{
if(link[x].Pre)
link[link[x].Pre].Sur = link[x].Sur;
else//if(x == head)
lh= link[x].Sur;
if(link[x].Sur)
link[link[x].Sur].Pre = link[x].Pre;
}
void BFS(int x)
{
f = r = 0;
LinkDel(x);
line[r++] = x;
while(f != r)
{
int t = line[f++];
for(int i = head[t]; i ; i = edge[i].next) hash[edge[i].v] = true;
for(int i = lh; i ; i = link[i].Sur)
if(!hash[i])
{
LinkDel(i);
line[r++] = i;
}
for(int i = head[t]; i ; i = edge[i].next) hash[edge[i].v] = false;
}
size[++ans] = r;
}
void read(int &x)
{
char c = getchar();
while(!(c >= '0' && c <= '9'))c = getchar();
x = 0;
while(c >= '0' && c <= '9')
x = (x<<3)+(x<<1) + (c-'0'), c = getchar();
}
void write(int x)
{
static char str[10]; int sl = 0;
while(x) str[++sl] = '0' + x%10, x /= 10;
if(!sl) {putchar('0');return;}
while(sl) putchar(str[sl--]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("biu.in","r",stdin);
freopen("biu.out","w",stdout);
#endif
read(n); read(m);
for(int i = 1,a,b; i <= m; i++)
{
read(a), read(b);
NewEdge(a,b);NewEdge(b,a);
}
BuildLink();
while(lh) BFS(lh);
std::sort(size+1,size+ans+1);
write(ans); puts("");
for(int i = 1; i <= ans; i++)
write(size[i]),putchar(' ');
fprintf(stderr,"%f",clock()*1.0/CLOCKS_PER_SEC);
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}