BZOJ2730 [HNOI2012]矿场搭建 - Tarjan割点
Solution
输入中没有出现过的矿场点是不用考虑的, 所以不用考虑只有 一个点 的点双联通分量。
要使某个挖矿点倒塌, 相当于割去这个点, 所以我们求一遍割点和点双联通分量。
之后的点双联通分量构成一棵树。 树上的节点有两种情况
1: 仅有一条边(仅有 一个割点 在内部)—— 相当与叶子节点, 把它与父亲节点相连的割点割去后,必须在里面设一个逃生出口
2: 大于一条边(有大于一个割点在内部 )——割去其中一个割点时, 还可以通过另一个割点到达逃生出口, 所以不用设置。
所以我们要求的就是在所有 仅含一个割点的 点双联通分量 内设置 一个 逃生出口, 并根据 乘法原理 计算方案数。
特别的: 当整个图是一个 点双连通图时, 设置任意 两个 逃生出口即可。
Code
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define rd read()
#define R register
#define ll long long
using namespace std; const int N = 1e3; int head[N], tot;
int dfn[N], low[N], col_num;//col_num为点双联通分量个数
int n, m, mark[N], cut[N], rt, maxn, cut_num[N];//cut_num为点双联通分量内的割点数
int st[N], tp, cnt;
ll ans1, ans2; vector<int> q[N];
struct edge {
int nxt, to, fr;
}e[N << ]; int read() {
int X = , p = ; char c = getchar();
for(; c > '' || c < ''; c = getchar()) if(c == '-') p = -;
for(; c >= '' && c <= ''; c = getchar()) X = X * + c - '';
return X * p;
} void add(int u, int v) {
e[++tot].to = v;
e[tot].nxt = head[u];
e[tot].fr = u;
head[u] = tot;
} void tarjan(int u) {
dfn[u] = low[u] = ++cnt;
st[++tp] = u;
int flag = ;
for(R int i = head[u]; i; i = e[i].nxt) {
R int nt = e[i].to;
if(!dfn[nt]) {
tarjan(nt);
low[u] = min(low[u], low[nt]);
if(low[nt] >= dfn[u]) {
col_num++;
flag ++;
if(flag > || u != rt)
cut[u] = ;
for(; tp;) {
int z = st[tp--];
q[col_num].push_back(z);
if(z == nt) break;
}
q[col_num].push_back(u);
}
} else low[u] = min(low[u], dfn[nt]);
}
} void init() {
for(int i = ; i <= col_num; ++i)
q[i].clear();
ans1 = maxn = col_num = cnt = tot = ;
ans2 = ;
memset(dfn, , sizeof(dfn));
memset(mark, , sizeof(mark));
memset(cut, , sizeof(cut));
memset(low, , sizeof(low));
memset(head, , sizeof(head));
memset(cut_num, , sizeof(cut_num));
} int main()
{
for(int T = ; ; T++) {
n = rd;
if(!n) return ;
init();
for(int i = ; i <= n; ++i) {
int u = rd, v = rd;
add(u, v); add(v, u);
mark[u] = mark[v] = ;
maxn = max(maxn, u);
maxn = max(maxn, v);
}
for(int i = ; i <= maxn; ++i)
if(!dfn[i] && mark[i]) tarjan(rt = i);
for(int i = ; i <= col_num; ++i)
for(int j = , len = q[i].size(); j < len; ++j) {
if(cut[q[i][j]]) cut_num[i]++;
}
for(int i = ; i <= col_num; ++i)
if(cut_num[i] == ) ans1++, ans2 = ans2 * (int)(q[i].size() - );
printf("Case %d: %lld %lld\n", T, ans1 ? ans1 : , ans1 ? ans2 : (int)(q[].size() - ) * q[].size()/ );
}
}
BZOJ2730 [HNOI2012]矿场搭建 - Tarjan割点的更多相关文章
- P3225 [HNOI2012]矿场搭建 tarjan割点
这个题需要发现一点规律,就是先按割点求块,然后求每个联通块中有几个割点,假如没有割点,则需要建两个出口,如果一个割点,则需要建一个出口,2个以上不用建. 题干: 题目描述 煤矿工地可以看成是由隧道连接 ...
- 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan
[BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...
- [BZOJ2730][HNOI2012]矿场搭建 点双 割点
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2852 Solved: 1344[Submit][Stat ...
- 【BZOJ-2730】矿场搭建 Tarjan 双连通分量
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1602 Solved: 751[Submit][Statu ...
- BZOJ 2730: [HNOI2012]矿场搭建( tarjan )
先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...
- BZOJ 2730:[HNOI2012]矿场搭建(割点+连通块)
[HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖 ...
- [HNOI2012]矿场搭建(割点)
[HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出 ...
- bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1147 Solved: 528[Submit][Statu ...
- [BZOJ2730][HNOI2012]矿场搭建(求割点)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2730 分析: 如果坍塌的点不是割点,那没什么影响,主要考虑坍塌的点是割点的情况. 显然 ...
随机推荐
- centos7里面docker不能下载本地源
报这种错的 编辑这个文件 加上这一段内容 rstart重启,搞定.
- el-js中循环遍历el的集合
遇到问题的代码: var score=0; for(var i=0;i<${fn:length(tMovie.tComments) };i++){ score=${tMovie.tComment ...
- VR/AR 科技了解
Dream学院学习资料: VR/AR科技学习需要先学习NDK技术 AR/VR->图像学->图像处理(OpenCV->Intel公司在1999年发布3.2).图像绘制渲染(OpenGL ...
- arguments对象的callee属性和caller属性
js中的arguments对象代表正在执行的函数和调用它的函数的参数.arguments对象有两个属性,callee和caller.collee表示当前正在执行的方法,caller表示调用该方法的对象 ...
- python全栈开发 随笔 'is' 和 == 的比较知识与区别 编码和解码的内容及转换
python 一. is 和 == 的区别; == 比较的是两边的值. a = 'alex' b = 'alex' print(a = b) #True a = 10 b = 10 print(a = ...
- MyLineNumberReader
package com.itheima; import java.io.FileReader; import java.io.IOException; import java.io.Reader; p ...
- 关于JavaScript全局作用域和函数作用域的拙见
在类c的语言中,用{}引起来的部分称为块级作用域,而在JS中没有块级作用域 作用域:一个变量作用的范围:中Js中一共有两种作用: 全局作用域 - 直接编写在script标签中的JS代码,都在全局作用域 ...
- node搭建简单的本地服务器
首先要安装node,方法很多,可以去网上找找,可以直接去官网下载安装,新版本的node是自带npm的: 安装好以后,新建一个js文件,名为server.js: let http = require(' ...
- 2019年华南理工大学程序设计竞赛(春季赛)-C-六学家的困惑
题目链接:https://ac.nowcoder.com/acm/contest/625/C 题意:给定两个字符串,每次只能从两个字符串的两端取字符,求依次取字符后所构成的数字最大为多少. 思路:思路 ...
- 前端 websocket用法
<!DOCTYPE html> <meta charset="utf-8" /> <title>WebSocket Test</title ...