题目链接:BZOJ - 1098

题目分析

只有两个点之间有边的时候它们才能在不同的楼内,那么就是说如果两个点之间没有边它们就一定在同一座楼内。

那么要求的就是求原图的补图的连通块。

然而原图的补图的边数是 n^2 级别的,非常庞大,我们不能直接把补图求出来。

可以使用一种用链表优化BFS的做法,开始时将所有的点加到一个链表里。

每次找一个连通块的时候BFS,在链表中取出一个点,在链表中删除,加入队列,然后每次取出队首元素x,枚举x的每一条边,将边的终点y从链表中删去,加到一个临时的链表中存储。

这样枚举完 x 的所有边之后,原链表里剩余的点就是与 x 没有边的,这些点在补图里与 x 就是有边的,将这些点加入队列。

然后用临时的链表替代原链表,原链表中就是剩下的点了。

这样BFS几次就可以求出所有连通块了。

每一个点都只被从链表中删去1次,每条边都只遍历了一次,总的时间复杂度是 O(n + m)。

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>using namespace std;const int MaxN = 100000 + 5, MaxM = 2000000 + 5;inline void Read(int &Num)
{char c; c = getchar();while (c < '0' || c > '9') c = getchar();Num = c - '0'; c = getchar();while (c >= '0' && c <= '9') {Num = Num * 10 + c - '0';c = getchar();}
}int n, m, Top, R1, R2, Sum;
int Ans[MaxN], Last[MaxN], Next[MaxN];bool InList[MaxN];struct Edge
{int v;Edge *Next;
} E[MaxM * 2], *P = E, *Point[MaxN];inline void AddEdge(int x, int y)
{++P; P -> v = y;P -> Next = Point[x]; Point[x] = P;
}queue<int> Q;inline void Add(int x, int y)
{Next[y] = Next[x];if (Next[x]) Last[Next[x]] = y;Next[x] = y;Last[y] = x;
}inline void Delete(int x)
{if (Last[x]) Next[Last[x]] = Next[x];if (Next[x]) Last[Next[x]] = Last[x];
}void BFS()
{while (!Q.empty()) Q.pop();Q.push(Next[R1]);InList[Next[R1]] = false;Delete(Next[R1]);int x, y;++Top;while (!Q.empty()) {x = Q.front();++Sum;++Ans[Top];Q.pop(); R2 = n + 2;Last[R2] = Next[R2] = 0;for (Edge *j = Point[x]; j; j = j -> Next){y = j -> v;if (!InList[y]) continue;Delete(y);Add(R2, y);}for (int i = Next[R1]; i; i = Next[i]) {Q.push(i);InList[i] = false;}Next[R1] = Next[R2];Last[Next[R1]] = R1;}
}int main()
{scanf("%d%d", &n, &m);int a, b;for (int i = 1; i <= m; ++i) {Read(a); Read(b);AddEdge(a, b);AddEdge(b, a);}Top = 0; Sum = 0;R1 = n + 1;for (int i = 1; i <= n; ++i) Add(R1, i);for (int i = 1; i <= n; ++i) InList[i] = true;while (Sum < n) BFS();printf("%d\n", Top);sort(Ans + 1, Ans + Top + 1);for (int i = 1; i <= Top; ++i) printf("%d ", Ans[i]);return 0;
}

  

转载于:https://www.cnblogs.com/JoeFan/p/4322722.html

[BZOJ 1098] [POI2007] 办公楼biu 【链表优化BFS】相关推荐

  1. 【BZOJ 1098】办公楼(补图连通块个数,Bfs)

    补图连通块个数这大概是一个套路吧,我之前没有见到过,想了好久都没有想出来QaQ 事实上这个做法本身就是一个朴素算法,但进行巧妙的实现,就可以分析出它的上界不会超过 $O(n + m)$. 接下来介绍一 ...

  2. 【HDU - 5009】Paint Pearls(dp,链表优化dp)

    题干: Lee has a string of n pearls. In the beginning, all the pearls have no color. He plans to color ...

  3. 程序员面试金典 - 面试题 04.03. 特定深度节点链表(BFS)

    1. 题目 给定一棵二叉树,设计一个算法,创建含有某一深度上所有节点的链表(比如,若一棵树的深度为 D,则会创建出 D 个链表).返回一个包含所有深度的链表的数组. 例: 输入:[1,2,3,4,5, ...

  4. BZOJ 2999 inint【数DP优化】(Ender的模拟赛)

    题目描述 从起点1开始,每次选择当前数的任意一位上加上去,问得到n的最小步数以及方案数.多组数据. 例如,从1开始得到100,有很多方法,其中有下面两种方式: A. 1-2-4-8-16-17-18- ...

  5. BZOJ.1109.[POI2007]堆积木Klo(DP LIS)

    BZOJ 二维\(DP\)显然.尝试换成一维,令\(f[i]\)表示,强制把\(i\)放到\(a_i\)位置去,现在能匹配的最多数目. 那么\(f[i]=\max\{f[j]\}+1\),其中\(j& ...

  6. BZOJ 1101: [POI2007]Zap

    题目 1101: [POI2007]Zap Time Limit: 10 Sec  Memory Limit: 162 MB Description FGD正在破解一段密码,他需要回答很多类似的问题: ...

  7. 算法提高课-搜索-Flood fill算法-AcWing 1098. 城堡问题:flood fill、bfs

    题目分析 来源:acwing 分析:找房间个数,也就是找连通的个数. 样例画出来的房间个数如下图:其中'|' 和'-'不是墙,只有#是墙. 分析:这题不用建图,直接bfs(flood fill)来做, ...

  8. bzoj 1632: [Usaco2007 Feb]Lilypad Pond【bfs】

    直接bfs,在过程中更新方案数即可 #include<iostream> #include<cstdio> #include<queue> using namesp ...

  9. BZOJ 1101: [POI2007]Zap( 莫比乌斯反演 )

    求 answer = ∑ [gcd(x, y) = d] (1 <= x <= a, 1 <= y <= b) . 令a' = a / d, b' = b / d, 化简一下得 ...

最新文章

  1. JDK5.0新特性系列---目录
  2. cacti监控一览无余
  3. .net函数查询_特来电智能分析平台动态查询架构创新实践
  4. 工作293:调节删除顺序删除
  5. Lyft Level 5 Challenge 2018 - Elimination Round翻车记
  6. 谷歌能否赶上「元宇宙」这趟快车?
  7. 小鱼的游泳时间(洛谷-P1425)
  8. 谈谈java中的集合框架
  9. php-5.6配置,PHP5.6+apache2.4环境配置
  10. 如何实现TextBox与DropDownList的级联
  11. Docker中配置国内镜像
  12. 全志r16android sdk,全志 Allwinner R16 SoC 全套设计资料分享 原理图 PCB 数据手册 SDK...
  13. CSS表格和表单的样式
  14. html5中Canvas API
  15. C# 四舍五入保留两位小数方法总结
  16. 超详细图文教程·阿里云免费学生ECS云服务器领取并使用全过程(部署Python多人聊天室程序)
  17. 区块链革命 - 第1篇 假如需要变革 - 第2章 区块链经济七大设计原则
  18. java金额小写转大写金额_Java金额大小写的转换方法
  19. Excel的Sumif函数
  20. css图像描边,纯CSS实现帅气的SVG路径描边动画效果

热门文章

  1. OpenCV alpha(权因子) 融合举例
  2. Harris及Shi-Tomasi原理及源码解析
  3. Android实现系统关机和重启
  4. C语言库函数的实战之一
  5. python核心编程-第六章-个人笔记(一)
  6. java httpclient 为邮箱添加来信转发规则
  7. resin管理后台登录配置
  8. 使用火炬之光资源(转)
  9. 学习js,尝试写一个表单验证框架(1)-规划
  10. 使用 C# 开发智能手机软件:推箱子(十二)