biu 分类: poi 2015-04-16 ...


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

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

转载于:https://www.cnblogs.com/dashgua/p/4723045.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值