【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】
2730: [HNOI2012]矿场搭建
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 3230 Solved: 1540
[Submit][Status][Discuss]
Description
Input
输入文件有若干组数据,每组数据的第一行是一个正整数 N(N≤500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖 S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。
Output
输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。
Sample Input
1 3
4 1
3 5
1 2
2 6
1 5
6 3
1 6
3 2
6
1 2
1 3
2 4
2 5
3 6
3 7
0
Sample Output
Case 2: 4 1
HINT
Solution
可以发现要找的特殊点的数量和图中割点有关。因为割点会把一个联通块分离成几块,导致中间断开,此时肯定需要增加安放的特殊点。
当把割点删去后分离成多个点双联通分量。
此时对每个点双进行讨论:
如果点双中与0个割点相邻,那么需要在点双中新增两个特殊点,防止其中一个特殊点挂了。
如果点双中与1个割点相邻,那么需要在点双中新增一个特殊点,为这个割点提供备用。
如果点双中与2个割点相邻,那么不需要增加特殊点,一个割点挂了可以走另一个割点离开。
然后就可以用乘法原理算出方案数了。
Code
#include<bits/stdc++.h>
#define LL long long
using namespace std; int n, m; struct Node {
int u, v, nex;
} Edge[]; int stot, h[];
void add(int u, int v) {
Edge[++stot] = (Node) {u, v, h[u]};
h[u] = stot;
} int dfn[], low[], idc, stk[], tp, cut[];
void Tarjan(int u, int fa) {
dfn[u] = low[u] = ++ idc;
stk[++tp] = u;
int son = ;
for(int i = h[u]; i; i = Edge[i].nex) {
int v = Edge[i].v;
if(i == (fa ^ )) continue;
if(!dfn[v]) {
son ++;
Tarjan(v, i);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u]) cut[u] = ;
} else low[u] = min(low[u], dfn[v]);
}
if(fa == && son == ) cut[u] = ;
} int siz, cut_num, cnt, color[];
void dfs(int u) {
color[u] = cnt;
if(cut[u]) return ;
siz ++;
for(int i = h[u]; i; i = Edge[i].nex) {
int v = Edge[i].v;
if(cut[v] && color[v] != cnt) {
cut_num ++; color[v] = cnt;
}
if(!color[v]) dfs(v);
}
} int main() {
int ti = ;
while(~scanf("%d", &m)) {
if(m == ) break;
n = ;
stot = ; memset(h, , sizeof(h));
cnt = ; tp = ; idc = ;
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(color, , sizeof(color));
memset(cut, , sizeof(cut));
for(int i = ; i <= m; i ++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
n = max(max(n, v), u);
}
for(int i = ; i <= n; i ++) if(!dfn[i]) Tarjan(i, );
LL ans1 = , ans2 = ;
for(int i = ; i <= n; i ++) {
if(!cut[i] && !color[i]) {
cnt ++; siz = , cut_num = ; dfs(i);
if(cut_num == ) { ans1 += ; ans2 *= 1ll * (siz - ) * siz / ;}
if(cut_num == ) { ans1 += ; ans2 *= siz;}
}
}
printf("Case %d: %lld %lld\n", ++ti, ans1, ans2);
}
return ;
}
【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】的更多相关文章
- BZOJ 2730: [HNOI2012]矿场搭建( tarjan )
先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...
- bzoj 2730: [HNOI2012]矿场搭建——tarjan求点双
Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...
- bzoj 2730: [HNOI2012]矿场搭建【tarjan】
先tarjan找割点和点双连通分量,然后对一个点双,如果没有割点,那么需要建立两个出口(割掉一个另一个备用):如果只有一个割点,出口可以设立在任意一个非割点的地方:如果有两个及以上个割点,就不用建出口 ...
- 【刷题】BZOJ 2730 [HNOI2012]矿场搭建
Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...
- bzoj 2730: [HNOI2012]矿场搭建
#include<cstdio> #include<cstring> #include<iostream> #define M 508 using namespac ...
- 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan
[BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...
- 【BZOJ2730】[HNOI2012] 矿场搭建(找割点)
点此看题面 大致题意: 一张无向图,要求你在去掉任意一个节点之后,剩余的每个节点都能到达一个救援出口,问至少需要几个救援出口. 第一步:\(Tarjan\)求割点 首先,我们要跑一遍\(Tarjan\ ...
- P3225 [HNOI2012]矿场搭建 tarjan割点
这个题需要发现一点规律,就是先按割点求块,然后求每个联通块中有几个割点,假如没有割点,则需要建两个出口,如果一个割点,则需要建一个出口,2个以上不用建. 题干: 题目描述 煤矿工地可以看成是由隧道连接 ...
- BZOJ2730 [HNOI2012]矿场搭建 - Tarjan割点
Solution 输入中没有出现过的矿场点是不用考虑的, 所以不用考虑只有 一个点 的点双联通分量. 要使某个挖矿点倒塌, 相当于割去这个点, 所以我们求一遍割点和点双联通分量. 之后的点双联通分量构 ...
随机推荐
- Linux内核Ramdisk(initrd)机制【转】
转自:http://www.cnblogs.com/armlinux/archive/2011/03/30/2396827.html 摘要:对于Linux用户来说,Ramdisk并不陌生,可是为什么需 ...
- java浅复制与深使用接口实现
1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...
- WPF中ListBox的绑定
WPF中列表式控件派生自ItemsControl类,继承了ItemsSource属性.ItemsSource属性可以接收一个IEnumerable接口派生类的实例作为自己的值(所有可被迭代遍历的集合都 ...
- Django Xadmin - 重构django admin
一.Django admin的执行流程 https://www.cnblogs.com/weihengblog/p/9122509.html 我的博客,介绍了django admin执行流程 二.Xa ...
- Django-模板语言和过滤器
Django模板语言 首先模板只是一个文本文件,它可以生成任何基于文本的格式(HTML.XML.CSS等),模板中包含变量,在模板被渲染的时候替换为最终的值,以及控制模板逻辑的标签. 变量使用{{ 变 ...
- 使用gradle编译安卓APK
一.安装JDK 在安装Gradle之前需要先安装JDK,由于安装的是Gradle是4.4所以需要安装JDK1.8. 之前编译总是提示如下错误就是由于先安装的jdk1.7然后安装的1.8造成的,在Gra ...
- Oracle 函数 “自动生成订单号”
create or replace function get_request_code return varchar2 AS --函数的作用:自动生成订单号 v_mca_no mcode_apply_ ...
- Linux入门(一)root密码设置和用户切换
从这学期开始,本人将会亲自开一个Linux 专题学习包括Linux 常用命令,常见问题的一些解决方法,以及Linux系统下C和C++一些学习经验 下面这张图片是首次安装Ubuntu后第一次设置root ...
- 读书笔记--C陷阱与缺陷(四)
第四章 1. 连接器 C语言的一个重要思想就是分别编译:若干个源程序可在不同的时候单独进行编译,恰当的时候整合到一起. 连接器一般与C编译器分离,其输入是一组目标模块(编译后的模块)和库文件,输出是一 ...
- NOIP2015 D2T3 运输计划
拿到题目的第一眼 首先这是一棵n个节点的树(别说你看不出来) 然后对于树上的m条链我们可以选取树上的唯一一条边使它的边权变为0 求处理后最长链的长度 20分 m=1好啦,好像可做一眼望去全是水 只需求 ...