bzoj 1098

求补图联通快数量,使用链表加速的bfs;

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int next[maxn],pre[maxn],head[maxn],t[maxn],tot=0,n,m,ans=0,way[maxn];
struct E{int to,next;E(int to=0,int next=0):to(to),next(next){}}edge[4000005];
void add(int x,int y){
    edge[++tot]=E(y,head[x]);head[x]=tot;
    edge[++tot]=E(x,head[y]);head[y]=tot;
}
void del(int k){
    next[pre[k]]=next[k];
    pre[next[k]]=pre[k];
}
void bfs(int x){
    queue<int> Q;
    Q.push(x);
    while(!Q.empty()){
        way[ans]++;
        int u=Q.front();Q.pop();
        for(int i=head[u];i;i=edge[i].next){int v=edge[i].to;t[v]=1;}
        for(int i=next[0];i<=n;i=next[i])if(!t[i]){Q.push(i);del(i);}

        for(int i=head[u];i;i=edge[i].next){int v=edge[i].to;t[v]=0;}
    }
}
int main(){//freopen("in.in","r",stdin);
    scanf("%d%d",&n,&m);int x,y;
    for(int i=0;i<=n;i++){next[i]=i+1;pre[i+1]=i;}
    for(int i=0;i<m;i++){scanf("%d%d",&x,&y);add(x,y);}
    for(int i=next[0];i<=n;i=next[0]){
        del(i);
        ans++,bfs(i);
    }
    printf("%d\n",ans);
    sort(way+1,way+1+ans);
    for(int i=1;i<=ans;i++)printf("%d ",way[i]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值