您的位置:首页 > 其它

bzoj 1098 poi2007 办公楼 bfs+链表

2017-07-10 21:18 155 查看
题意很好理解,求给出图反图的联通块个数。

考虑这样一个事情:一个联通块里的点,最多只会被遍历一次,再遍历时没有任何意义

所以用链表来存,每遍历到一个点就将该点删掉

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define N 100005
int e=1,head
,n,m;
int nxt
,ans,pre
,final
,tot,q
;
bool bo
,flag
;
struct edge{
int u,v,next;
}ed[4000005];
void add(int u,int v)
{
ed[e].v=v;
ed[e].next=head[u];
head[u]=e++;
}
void del(int x){
nxt[pre[x]]=nxt[x];
pre[nxt[x]]=pre[x];
}
void bfs(int x)
{
int h=1,t=1;
q[1]=x;
while(h<=t){
int now=q[h++]; ans++;
for(int i=nxt[0];i<=n;i=nxt[i]) bo[i]=0;
for(int i=head[now];i;i=ed[i].next)
bo[ed[i].v]=1;
for(int i=nxt[0];i<=n;i=nxt[i]){
if(!bo[i]){
del(i); q[++t]=i;
}
}
}
}
int main()
{
int u,v;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
add(u,v); add(v,u);
}
nxt[0]=1;
for(int i=1;i<=n+1;i++){
pre[i]=i-1;
nxt[i]=i+1;
}
tot=0;
for(int i=nxt[0];i<=n;i=nxt[0]){
ans=0;
del(i); bfs(i);
final[++tot]=ans;
}
sort(final+1,final+tot+1);
printf("%d\n",tot);
for(int i=1;i<=tot;i++)
printf("%d ",final[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: