【BZOJ1098】办公楼biu(补图,bfs,链表)

题意:有n个点m条边,要求将点尽可能多的分成若干个部分,使得若两个点不在同一个部分则他们之间必定有边

n<=1e5,m<=2e6

思路:From https://blog.csdn.net/clover_hxy/article/details/52980373

转化为求补图联通分量的个数和size,主要是枚举点用链表优化,整体可以做到不带log

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef long double ld;
  7 typedef pair<int,int> PII;
  8 typedef pair<ll,ll> Pll;
  9 typedef vector<int> VI;
 10 typedef vector<PII> VII;
 11 typedef pair<ll,ll>P;
 12 #define N  500010
 13 #define M  1000000
 14 #define INF 1e9
 15 #define fi first
 16 #define se second
 17 #define MP make_pair
 18 #define pb push_back
 19 #define pi acos(-1)
 20 #define mem(a,b) memset(a,b,sizeof(a))
 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 23 #define lowbit(x) x&(-x)
 24 #define Rand (rand()*(1<<16)+rand())
 25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 26 #define ls p<<1
 27 #define rs p<<1|1
 28 #define fors(i) for(auto i:e[x]) if(i!=p)
 29 
 30 const int MOD=1e9+7,inv2=(MOD+1)/2;
 31       double eps=1e-6;
 32       int dx[4]={-1,1,0,0};
 33       int dy[4]={0,0,-1,1};
 34 
 35 VI c[N];
 36 int pre[N],nxt[N],vis[N],q[N],a[N],ans,n,m;
 37 
 38 
 39 int read()
 40 {
 41    int v=0,f=1;
 42    char c=getchar();
 43    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 44    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 45    return v*f;
 46 }
 47 
 48 ll readll()
 49 {
 50    ll v=0,f=1;
 51    char c=getchar();
 52    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 53    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 54    return v*f;
 55 }
 56 
 57 void del(int u)
 58 {
 59     int t=pre[u];
 60     nxt[t]=nxt[u];
 61     pre[nxt[u]]=t;
 62 }
 63 
 64 void bfs(int st)
 65 {
 66     int t=0,w=1;
 67     q[1]=st;
 68     while(t<w)
 69     {
 70         a[ans]++;
 71         t++;
 72         int u=q[t];
 73         for(int i=0;i<c[u].size();i++)
 74         {
 75             int v=c[u][i];
 76             vis[v]=1;
 77         }
 78         for(int i=nxt[0];i<=n;i=nxt[i])
 79          if(!vis[i]) del(i),q[++w]=i;
 80         for(int i=0;i<c[u].size();i++)
 81         {
 82             int v=c[u][i];
 83             vis[v]=0;
 84         }
 85     }
 86 }
 87 
 88 int main()
 89 {
 90     n=read(),m=read();
 91     rep(i,0,n) nxt[i]=i+1;
 92     rep(i,1,n+1) pre[i]=i-1;
 93     rep(i,1,m)
 94     {
 95         int x=read(),y=read();
 96         c[x].pb(y);
 97         c[y].pb(x);
 98     }
 99     ans=0;
100     for(int i=nxt[0];i<=n;i=nxt[0])
101     {
102         del(i);
103         ans++;
104         bfs(i);
105     }
106     printf("%d\n",ans);
107     sort(a+1,a+ans+1);
108     rep(i,1,ans) printf("%d ",a[i]);
109     return 0;
110 }

 

posted on 2019-11-11 14:33  myx12345  阅读(147)  评论(0编辑  收藏  举报

导航