biu 分类: poi 2015-04-16 10:03 31人阅读 评论(0) 收藏

老子叫甜甜 提交于 2020-03-04 22:47:48

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!