题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1098

首先,没有连边的人一定得在一个连通块里;

先把所有人连成一个链表,然后从第一个人开始,把和它有连边的人都打上标记,没有标记的就加入栈里,并在链表中删除;

只要栈里还有值,就重复这个操作,把必须和栈顶元素在一个连通块的元素也都找出来加入栈,同时 siz++;

因为链表维护,所以遍历人的复杂度总体是 O(n) 的,再加上遍历边的复杂度,算下来是 O(n+m);

关键在于用链表降低遍历人的复杂度!很好的思路。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const xn=1e5+,xm=2e6+;
int n,m,hd[xn],ct,to[xm<<],nxt[xm<<],vis[xn],pr[xn],nt[xn],siz[xn],cnt;
int sta[xn],top;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void del(int x){nt[pr[x]]=nt[x]; pr[nt[x]]=pr[x];}
int main()
{
n=rd(); m=rd();
for(int i=,x,y;i<=m;i++)
{
x=rd(); y=rd();
add(x,y); add(y,x);
}
for(int i=;i<=n;i++)pr[i]=i-,nt[i]=i+;
int i=; nt[]=; pr[n+]=n;
while(nt[]!=n+)
{
i=nt[]; del(i);
for(int j=hd[i];j;j=nxt[j])vis[to[j]]=i;
sta[++top]=i; siz[++cnt]=;
while(top)
{
int x=sta[top]; top--;
for(int k=hd[x];k;k=nxt[k])vis[to[k]]=x; vis[x]=x;
int nww=nt[];
while(nww!=n+)
{
if(vis[nww]!=x)siz[cnt]++,sta[++top]=nww,del(nww);
nww=nt[nww];
}
}
}
printf("%d\n",cnt);
sort(siz+,siz+cnt+);
for(int i=;i<=cnt;i++)printf("%d ",siz[i]);
return ;
}

bzoj 1098 办公楼biu —— 链表+栈的更多相关文章

  1. bzoj 1098 [POI2007]办公楼biu——链表

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1098 求补图的连通块大小.与自己没有边的和自己在一个连通块里. 用链表把所有点串起来.先给自 ...

  2. BZOJ 1098: [POI2007]办公楼biu 链表

    求补图连通块,用链表优化,势能O(n+m) #include<cstdio> #include<cstring> #include<iostream> #inclu ...

  3. [BZOJ 1098] [POI2007] 办公楼biu 【链表优化BFS】

    题目链接:BZOJ - 1098 题目分析 只有两个点之间有边的时候它们才能在不同的楼内,那么就是说如果两个点之间没有边它们就一定在同一座楼内. 那么要求的就是求原图的补图的连通块. 然而原图的补图的 ...

  4. bzoj 1098 [POI2007]办公楼biu bfs+补图+双向链表

    [POI2007]办公楼biu Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1543  Solved: 743[Submit][Status][Di ...

  5. BZOJ1098: [POI2007]办公楼biu

    从问题可以看出是求补图的连通块及点数 但补图太大.所以考虑缩小规模. 当一个点归属于一个连通块后,它以后就不需要了.所以可以用链表,删去这个点,也就减小了规模. 一个点开始bfs,每个点只会进队一次, ...

  6. 5098: [BZOJ1098][POI2007]办公楼biu

    5098: [BZOJ1098][POI2007]办公楼biu 没有数据结构就很棒 一个看上去非常玄学的代码 const int N=1e5+10,M=2e6+10; int n,m; int fa[ ...

  7. BZOJ 2080: [Poi2010]Railway 双栈排序

    2080: [Poi2010]Railway Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 140  Solved: 35[Submit][Statu ...

  8. C语言 复杂的栈(链表栈)

    //复杂的栈--链表栈 #include<stdio.h> #include<stdlib.h> #define datatype int//定义链表栈数据类型 //定义链表栈 ...

  9. BZOJ_1098_[POI2007]办公楼biu_链表优化BFS

    BZOJ_1098_[POI2007]办公楼biu_链表优化BFS Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的 电话号 ...

随机推荐

  1. mysql索引底层的数据结构和算法

    1.       为什么要用索引 索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构.索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要. 索 ...

  2. 洛谷P1061 Jam的计数法

    题目描述 Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字 ...

  3. 使用ftrace学习linux内核函数调用

    http://www.cnblogs.com/pengdonglin137/articles/4752082.html 转载: http://blog.csdn.net/ronliu/article/ ...

  4. 三角网格上的寻路算法Part.1—Dijkstra算法 等

    http://www.cnblogs.com/chnhideyoshi/p/AStar.html

  5. dwarf调试信息格式入门

    https://www.prevanders.net/dwarf.html#testingcomment http://www.dwarfstd.org/ http://www.cnblogs.com ...

  6. LayUI后台管理与综合示例

    一.LayUI介绍 layui(谐音:类UI) 是一款采用自身模块规范编写的前端 UI 框架,遵循原生 HTML/CSS/JS 的书写与组织形式,门槛极低,拿来即用.其外在极简,却又不失饱满的内在,体 ...

  7. Android新技术学习——阿里巴巴免Root无侵入AOP框架Dexposed

    阿里巴巴无线事业部近期开源的Android平台下的无侵入运行期AOP框架Dexposed,该框架基于AOP思想,支持经典的AOP使用场景.可应用于日志记录,性能统计,安全控制.事务处理.异常处理等方面 ...

  8. Effective C++ 条款四 确定对象被使用前已被初始化

    1.对于某些array不保证其内容被初始化,而vector(来自STL)却有此保证. 2.永远在使用对象前初始化.对于无任何成员的内置类型,必须手工完成.      int x = 0;      c ...

  9. 传奇的诞生,PHP三位创始人简介

    PHP到现在为止已经诞生12年了.在这期间它经过不断改善,已经成为Web开发最重要的语言之一.PHP能有今天这样的成就,它的3位创始人(Rasmus Lerdorf.Zeev Suraski和Andi ...

  10. Linux编程---进程通信

    Linux的通信方式主要有分类有以下几种: -匿名管道和FIFO有名管道 -消息队列,信号量和共享存储 -套接字 对于套接字的进程通信,我就留在套接字的文章中再写了. 一.管道 管道是最古老的进程通信 ...