【BZOJ 1098】办公楼(补图连通块个数,Bfs)
补图连通块个数这大概是一个套路吧,我之前没有见到过,想了好久都没有想出来QaQ
事实上这个做法本身就是一个朴素算法,但进行巧妙的实现,就可以分析出它的上界不会超过 $O(n + m)$。
接下来介绍一下这个技巧:
很显然一个不在原图中的边一定在补图中出现,如果我们考虑用朴素的$Bfs$求一个图中的连通块个数,对于当前的一个点$x$,枚举它连出去的边进行拓展即可。
如果是求补图中的,那对于当前队首的点$x$,可以枚举其他所有的点,看是否和这个点有连边,没有就拓展。
一个可以的优化就是,一个点在$Bfs$是不会被入队多次,我们可以把它删掉,这样可以优化原先朴素算法在拓展上$O(n)$枚举的复杂度。
至于为什么删掉不会造成问题,我们可以考虑它有可能存在的问题就是某一个点$x$在拓展的时候准备拓展一个已经被删除的点$y$,那可能会造成原本在一个连通块的点分成多个,这种情况下在之前$y$拓展的时候就会先拓展到$x$;至于如果两个点同时被删除时,那它们一定是同一个根,一定是同一个连通块里的。
接下来证明这样优化之后复杂度的上界是$O(n + m)$:
事实上我们进行每一次拓展的时候,一次失败的拓展是因为原图中存在着这条边,而一旦拓展成功,就能删掉一个点。由于每条边做多被访问一次,于是每次拓展就是要么是减少一条边,要么是减少一个点,故$Bfs$的复杂度上界是$O(n + m)$的。
这个题就是一个例子,在此做一个总结:
#include <cstdio>
#include <queue>
#include <algorithm> using namespace std; const int N = ; int n, m;
int fa[N], vis[N];
vector<int> g[N], ans; int Sk(int x) {
return fa[x] == x? x : fa[x] = Sk(fa[x]);
} void Bfs(int s) {
static queue<int> Q;
Q.push(s), fa[s] = Sk(s + );
ans.push_back();
for (int x; !Q.empty(); ) {
x = Q.front(), Q.pop();
for (int v : g[x]) vis[v] = x;
for (int i = Sk(); i <= n; i = Sk(i + )) {
if (vis[i] != x) fa[i] = Sk(i + ), Q.push(i), ++ans.back();
}
}
} int main() {
scanf("%d%d", &n, &m);
for (int i = , x, y; i <= m; ++i) {
scanf("%d%d", &x, &y);
g[x].push_back(y), g[y].push_back(x);
}
for (int i = ; i <= n; ++i) fa[i] = i;
fa[n + ] = n + ;
for (int i = ; i <= n; i = Sk(i + )) Bfs(i);
sort(ans.begin(), ans.end());
printf("%d\n", (int)ans.size());
for (int i : ans) printf("%d ", i);
putchar('\n'); return ;
}
【BZOJ 1098】办公楼(补图连通块个数,Bfs)的更多相关文章
- Codeforces 920E Connected Components? 补图连通块个数
题目链接 题意 对给定的一张图,求其补图的联通块个数及大小. 思路 参考 ww140142. 维护一个链表,里面存放未归入到任何一个连通块中的点,即有必要从其开始进行拓展的点. 对于每个这样的点,从它 ...
- 求连通块个数 - BFS、DFS、并查集实现
本文基于leetcode的200.岛屿数量(题目
- P1197 [JSOI2008]星球大战 [删边求连通块个数]
展开 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的 ...
- ZOJ 1709 Oil Deposits(dfs,连通块个数)
Oil Deposits Time Limit: 2 Seconds Memory Limit: 65536 KB The GeoSurvComp geologic survey compa ...
- bzoj 1098 办公楼biu —— 链表+栈
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1098 首先,没有连边的人一定得在一个连通块里: 先把所有人连成一个链表,然后从第一个人开始, ...
- bzoj 1015 维护连通块个数,离线并查集
水. /************************************************************** Problem: 1015 User: idy002 Langua ...
- DFS:POJ1562-Oil Deposits(求连通块个数)
Oil Deposits Time Limit: 1000MS Memory Limit: 10000K Description The GeoSurvComp geologic survey com ...
- BZOJ 1098: [POI2007]办公楼biu 链表
求补图连通块,用链表优化,势能O(n+m) #include<cstdio> #include<cstring> #include<iostream> #inclu ...
- hdu 1241 Oil Deposits(DFS求连通块)
HDU 1241 Oil Deposits L -DFS Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & ...
随机推荐
- Hyperledger Fabric Capabilities——超级账本功能汇总
Hyperledger Fabric是一种模块化的区块链架构,是分布式记账技术(DLT)的一种独特的实现,它提供了可供企业运用的网络,具备安全.可伸缩.加密和可执行等特性.Hyperledger Fa ...
- IPC_Binder_java_2
title: IPC_Binder_java_2 date: 2017-07-04 14:47:55 tags: [IPC,Binder] categories: [Mobile,Android] - ...
- 微软职位内部推荐-SW Engineer II for Enterprise Platform
微软近期Open的职位: Job posting title: SDE II Location: China, Beijing Group Overview Discovery & Colla ...
- 【Alpha】阶段第九次Scrum Meeting
[Alpha]阶段第九次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 编写获得所有学院接口 登出接口 赵智源 编写alpha版后测试点测试用例 编写脚本实现测 ...
- Android笔记-2-TextView的属性详解
[Android 基础]TextView的属性详解 android:autoLink :设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接.可选值(none/web / ...
- 第一次spring冲刺第7天
讨论成员:王俊凯.王逸辉.罗凯杰.马志磊 讨论问题:进行UI设计的详细讨论,虽然结果各有争议,但最终确定了较为简单的布局页面,并且开始收集精美页面的案例 冲刺尚未结束,同志还需努力,致力于最后.
- week3c:个人博客作业
程序测试: 一个基本的测试. 在Visual Studio 2013 中使用C++单元测试 操作如下: 这是我学到的过程. 有复杂程序的测试.以后有时间再弄.
- 标头 header()函数的用法
头 (header) 是服务器以 HTTP 协议传 HTML 资料到浏览器前所送出的字串,在标头与 HTML 文件之间尚需空一行分隔. 范例一: 本例使浏览器重定向到 PHP 的官方网站. <? ...
- TADOConnection.Close - connection still active on MS-SQL server
I have several Delphi programs (XE3), that use a TADOConnection to connect to a MS-SQL Server. I rec ...
- vue 大概流程(未完)
规划组件结构 编写对应路由 具体写每个组件功能