P3452 [POI2007]BIU-Offices(链表+bfs)

P3452 [POI2007]BIU-Offices

新姿势:链表存图快速删除

显然两个没有直接相连的点要放到同一个集合里

但是直接搞一个图的补图会挂掉

考虑用链表维护点序列

每次bfs删除一个点和与其没有直接相连的点

复杂度大概。。。能过

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int read(){
    char c=getchar(); int x=0;
    while(c<'0'||c>'9') c=getchar();
    while('0'<=c&&c<='9') x=x*10+c-48,c=getchar();
    return x;
}
#define N 100005
#define M 4000005
int n,m,pr[N],nx[N],ans,pos[N]; bool is[N];
int Cnt,hd[N],nxt[M],ed[N],poi[M];
void adde(int x,int y){
    nxt[ed[x]]=++Cnt; hd[x]=hd[x]?hd[x]:Cnt;
    ed[x]=Cnt; poi[Cnt]=y;
}
void del(int x){nx[pr[x]]=nx[x]; pr[nx[x]]=pr[x];}
#define to poi[i]
void bfs(int S){
    queue <int> h; h.push(S);
    while(!h.empty()){
        int x=h.front(); h.pop(); ++pos[ans];
        for(int i=hd[x];i;i=nxt[i]) is[to]=1;
        for(int i=nx[0];i<=n;i=nx[i])
            if(!is[i]) del(i),h.push(i);
        for(int i=hd[x];i;i=nxt[i]) is[to]=0;
    }
}
int main(){
    n=read(); m=read();
    for(int i=0;i<=n+1;++i) pr[i]=i-1,nx[i]=i+1;
    for(int i=1,u,v;i<=m;++i)
        u=read(),v=read(),adde(u,v),adde(v,u);
    for(int i=nx[0];i<=n;i=nx[0]) ++ans,del(i),bfs(i);
    sort(pos+1,pos+ans+1);
    printf("%d
",ans);
    for(int i=1;i<=ans;++i) printf("%d ",pos[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/kafuuchino/p/11343351.html