首页 > 代码库 > BZOJ 1098: [POI2007]办公楼biu 链表

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;
}

 

BZOJ 1098: [POI2007]办公楼biu 链表