BZOJ 1098: [POI2007]办公楼biu 链表
求补图连通块,用链表优化,势能O(n+m)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 100010 using namespace std; inline int read() { int sum=0; char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9') { sum=(sum<<1)+(sum<<3)+ch-48; ch=getchar(); } return sum; } int Next[MAXN],pre[MAXN]; int belong[MAXN]; int mark[MAXN]; struct Tree { int to,Next; }c[MAXN*40]; int head[MAXN],t; int n,m,sz; inline void add(int x,int y) { c[++t].to=y; c[t].Next=head[x]; head[x]=t; } inline void Init() { n=read(); m=read(); for(int i=1;i<=m;i++) { int x=read(),y=read(); add(x,y); add(y,x); } Next[0]=1; pre[1]=0; for(int i=1;i<=n;i++) { Next[i]=i+1; pre[i+1]=i; } } int q[MAXN],top,tail; void dfs(int x,int now) { belong[x]=now; for(int i=head[x];i;i=c[i].Next) mark[c[i].to]=x; for(int i=Next[0];i<=n;i=Next[i]) if(mark[i]!=x) { q[++tail]=i; Next[pre[i]]=Next[i]; pre[Next[i]]=pre[i]; } } inline void bfs(int s,int now) { top=tail=1; q[1]=s; Next[pre[s]]=Next[s]; pre[Next[s]]=pre[s]; while(top<=tail) { int x=q[top++]; dfs(x,now); } } int f[MAXN]; inline void work() { for(int x=1;x<=n;x++) if(!belong[x]) { ++sz; bfs(x,sz); } } inline void print() { for(int i=1;i<=n;i++) f[belong[i]]++; sort(f+1,f+sz+1); printf("%d\n",sz); for(int i=1;i<=sz;i++) printf("%d ",f[i]); } int main() { Init(); work(); print(); return 0; }
苟利国家生死以, 岂因祸福避趋之。