[luoguP3325][HNOI2012]矿场搭建
P3225 [HNOI2012]矿场搭建
题目描述
煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。
请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。
输入输出格式
输入格式:
输入文件有若干组数据,每组数据的第一行是一个正整数 N(N<=500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖 S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。
输出格式:
输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。
首先这个题首先我们讨论两种情况,第一种情况就是这个图本来就是一个点连通图,也就是说不存在割点。那么我们任意去掉一个点以后,这个图仍然是联通的。那么我们的逃生出口一定要有两个,保证如果一个逃生出口Over了,还有另外一个逃生出口可以保命。所以总方案数就是Cn2 。
然后第二种情况,这个图存在割点。那么如果坍塌的是这个割点,这个图就会变得不连通。对于那种只和一个割点相连的块,我们至少要在这个块里面选出来一个建逃生通道,而且也是任意选择。假设这个块有p个节点,那么该块的方案数就是Cp-11。(有一个割点所以-1)(p为该块的点数)
针对第二种情况总结来看对于每一个双联通分量我们一共有三种情况:
1.如果这个双联通分量里面没有割点。那么在这个双联通分量里面需要建Cp2个出口。
2.如果双联通分量只有一个割点,那么再非割点的地方任意选择一个点来建逃生出口都没有问题。方案数为Cp-11。
3.若该双联通分量里面有两个割点,那么我们就不需要建立了,因为无论哪一个节点hehe了,其他的点都可以通过其他的没有hehe的点跑到别的双联通分量里面去。
然后以上是针对一个双联通分量的,那么至于总共的方案,我们就可以利用一下组合数学了.....(qwq)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define INF 0x7fffffff
#define MAXN 100010
#define ll long long
using namespace std;
int n,m;
struct point{
int from;
int to;
int next;
}edge[MAXN*2];
int total,head[MAXN];
void add(int f,int t){
total++;
edge[total].from=f;
edge[total].to=t;
edge[total].next=head[f];
head[f]=total;
}
int Yeasion[MAXN],Nein[MAXN];
int stack[MAXN],top,ken;
vector<int>block[MAXN];
int cut[MAXN],cnt,root;
void Tarjan(int now,int fa){
Yeasion[now]=Nein[now]=++ken;
stack[++top]=now; int child=0;
for(int i=head[now];i;i=edge[i].next){
if(!Yeasion[edge[i].to]){
Tarjan(edge[i].to,now); child++;
Nein[now]=min(Nein[now],Nein[edge[i].to]);
if(now==root&&child>1) cut[now]=1;
if(now!=root&&Yeasion[now]<=Nein[edge[i].to]) cut[now]=1;
if(Yeasion[now]<=Nein[edge[i].to]){
cnt++; block[cnt].clear();
int pass;
do{
pass=stack[top--];
block[cnt].push_back(pass);
}while(pass!=edge[i].to);/////
block[cnt].push_back(now);
}
}
else Nein[now]=min(Nein[now],Yeasion[edge[i].to]);
}
}
void Solve(){
n=0;
for(int i=1;i<=m*2;i++){
Yeasion[i]=Nein[i]=0;
head[i]=0;
cut[i]=0;
}top=ken=cnt=0;
for(int i=1;i<=m;i++){
int x; int y;
scanf("%d%d",&x,&y);
n=max(n,max(x,y));
add(x,y); add(y,x);
};
for(int i=1;i<=n;i++){
if(!Yeasion[i]){
root=i;
Tarjan(i,-1);
}
}
ll res=0,num=1;
for(int i=1;i<=cnt;i++){
int yor=0;
int len=block[i].size();
for(int j=0;j<len;j++)
if(cut[block[i][j]]) yor++;
if(yor==0) res+=2,num=num*(len-1)*len/2;
else if(yor==1) res++,num=num*(len-1);
}
printf("%lld %lld\n",res,num);
}
int main(){
int t=1;
while(scanf("%d",&m)&&m){
printf("Case %d: ",t++);
Solve();
} return 0;
}
[luoguP3325][HNOI2012]矿场搭建的更多相关文章
- bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1147 Solved: 528[Submit][Statu ...
- BZOJ 2730: [HNOI2012]矿场搭建( tarjan )
先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...
- 洛谷 P3225 [HNOI2012]矿场搭建 解题报告
P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...
- 【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3230 Solved: 1540[Submit][Stat ...
- Tarjan 点双+割点+DFS【洛谷P3225】 [HNOI2012]矿场搭建
P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...
- [BZOJ2730][HNOI2012]矿场搭建 点双 割点
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2852 Solved: 1344[Submit][Stat ...
- 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan
[BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...
- BZOJ 2730:[HNOI2012]矿场搭建(割点+连通块)
[HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖 ...
- BZOJ_2730_ [HNOI2012]矿场搭建_点双联通分量
BZOJ_2730_ [HNOI2012]矿场搭建_点双联通分量 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路 ...
随机推荐
- Excel&&word&&PPT
1. Excel 1.1 制作下拉框 选中单元格或列--> 菜单"数据" --> "数据验证"-->"设置" --> ...
- 1.1 js基础
2.代码从上往下,从左往右执行. 函数声明在哪里不重要,重要的是在哪里调用. undefined 未定义 3.数据类型 12,5 number 'abc' 字 ...
- java io 学习笔记(一)
java的IO操作都在java.io包下面,这个包下面有12个接口和而是多各类,类从读写的角度可以分为两种,一种是用于读,一种是用于写:从字符流字节流的角度,也可以分为两种,一种和字符有关,一种和字节 ...
- Python 集合(set)类型的操作——并交差
介绍 python的set是一个无序不重复元素集,基本功能包括关系测试和消除重复元素. 集合对象还支持并.交.差.对称差等. sets 支持 x in set. len(set).和 for x in ...
- ajax返回数据之前的loading等待
首先,我们通过ajax请求,向后台传递参数,然后后台经过一系列的运算之后向前台返还数据,我希望在等待数据成功返还之前可以展示一个loading.gif图 不废话,在页面上执行点击事件(<a sc ...
- php 不用第三个变量 交换两个变量的值汇总
//方法一:$a ="abc";$b="def"; $a = $a^$b;$b = $b^$a;$a = $a^$b; //方法二:list($a, $b)= ...
- 6、Modal
1.首先Modal是一个内容窗格.通常用来做一个选择或编辑. 先来看一下 tabs.html 做了什么. /* --- tabs.html ----*/ <ion-navbar *navbar ...
- netty笔记(一)--Demo
Netty是一个Java开源框架,用于传输数据.由server和client组成,封装了Java nio,支持TCP, UDP等协议.这里写了一Demo EchoClientHandler.java ...
- scss-比较运算符
与JavaScript类似,scss中也有比较运算符,下面就分别做一下介绍. 一.==相等和!=不相等运算符: 此运算符用来判断两个操作数是否相等. 特别说明: 上面两个运算符,支持类似于JavaSc ...
- Python爬虫《Python网络爬虫相关基础概念》
引入 之前在授课过程中,好多同学都问过我这样的一个问题:为什么要学习爬虫,学习爬虫能够为我们以后的发展带来那些好处?其实学习爬虫的原因和为我们以后发展带来的好处都是显而易见的,无论是从实际的应用还是从 ...