# BZOJ1098: [POI2007]办公楼biu

$n \leq 100000$个点，$m \leq 2000000$条边，给点分组，两个点能在不同组必须两点之间有边，问最多分多少组以及每组人数。

 1 #include<stdio.h>
2 #include<string.h>
3 //#include<queue>
4 #include<stdlib.h>
5 #include<algorithm>
6 //#include<iostream>
7 using namespace std;
8
9 #define LL long long
11 {
12     char c; int s=0,t=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (t=-1);
13     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*t;
14 }
15
16 //Pay attention to LL and double of qread!!!!
17
18 int n,m;
19 #define maxn 100011
20 #define maxm 4000011
21 struct Edge{int to,next;}edge[maxm]; int first[maxn],le=2;
22 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
23 void insert(int x,int y) {in(x,y); in(y,x);}
24
26 void Del(int x) {ll[rr[x]]=ll[x]; rr[ll[x]]=rr[x];}
27 int main()
28 {
31
32     for (int i=0;i<=n+1;i++) ll[i]=i-1,rr[i]=i+1;
33     int tot=0;
34     while (rr[0]<=n)
35     {
37         tot++; size[tot]=1;
39         {
41             for (int i=first[x];i;i=edge[i].next) vis[edge[i].to]=1;
42             for (int j=rr[0];j<=n;j=rr[j]) if (!vis[j]) {que[tail++]=j; Del(j); size[tot]++;}
43             for (int i=first[x];i;i=edge[i].next) vis[edge[i].to]=0;
44         }
45     }
46     sort(size+1,size+1+tot);
47     printf("%d\n",tot);
48     for (int i=1;i<=tot;i++) printf("%d ",size[i]);
49     return 0;
50 }
View Code

posted @ 2018-05-03 19:23  Blue233333  阅读(201)  评论(0编辑  收藏  举报