洛谷P3225 HNOI2012 矿场搭建
题目描述
煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。
请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。
输入输出格式
输入格式:
输入文件有若干组数据,每组数据的第一行是一个正整数 N(N<=500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖 S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。
输出格式:
输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。
输入输出样例
9
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
Case 1: 2 4
Case 2: 4 1
这道题是我在不会双联通分量时写的(虽然是COPY的题解)
于是有了一个割点TARJAN的思路 首先跑一个TARJAN求出所有割点
然后我本来想对于每一个割点的周围进行DFS 但是发现这样写不出来(没法判重也没法计数)
于是看了题解 =_= 发现他是对于每一个块进行DFS 在割点处停止以划分块
设一个块里有NUM个不是割点的点
对于每个块 如果有2个及以上割点 则不需要建出口
如果有1个割点 则要建一个出口 方案数为NUM
如果没有割点 则要建2个出口 方案数为NUM*(NUM-1)/2
在搜索每个块的时候记得要染色而不是访问(=——=)
因为访问的话
- 如果你标记割点 将导致另一个块遍历不到这个割点
- 如果你不标记割点 将导致当前块其他点找到这个割点时重复计数
但是染色就不会有上面的问题 跑一遍爽就完事了 这题数据十分的水
上满分代码(本蒟蒻调了40MIN的说 = =)
#include<bits/stdc++.h>
#define MAXN 20010
#define MAXM 100010 using namespace std; struct Edge{
int to,nxt;
}edge[MAXM*];
int head[MAXN],ectr,n,m;
void addedge(int from,int to){
ectr++;
edge[ectr].to = to;
edge[ectr].nxt = head[from];
head[from] = ectr;
}
long long NUM,CUT,ans1,ans2,color;
int dfn[MAXN],low[MAXN];
long long cv_ctr,tp,root;
int vis[MAXN];
bool cv[MAXN]; void tarjan(int u){//let's go
dfn[u] = low[u] = ++tp;
int flag = ;
for(int i=head[u] ; i ; i=edge[i].nxt){
int v=edge[i].to;
if( !dfn[v] ) {
tarjan(v);
low[u] = min(low[u],low[v]);
if(low[v] >= dfn[u]){
flag++;
if(u != root || flag > ) {
if(cv[u] == false){
cv_ctr++;
cv[u] = true;
}
}
}
}
else low[u]=min(low[u],dfn[v]);
}
} void dfs(int x){
NUM ++;
vis[x] = color; for(int i=head[x];i;i=edge[i].nxt){
int y=edge[i].to;
if( cv[y] && vis[y] != color ) {
vis[y] = color;
CUT ++ ;
continue;
}
else {
if( !vis[y] && !cv[y] ) dfs(y);
}
}
return ;
} int main(){
int SDF=;
while(scanf("%d",&m) && m!=){ memset(edge,,sizeof edge);
memset(head,,sizeof head);
memset(low,,sizeof low);
memset(dfn,,sizeof dfn);
memset(cv,false,sizeof cv);
memset(vis,,sizeof vis);
ans2=;
cv_ctr = tp = ans1 = root = ;
ectr = n = NUM = CUT = color = ;
ans2 = ;
for(int i=;i<=m;i++){
int tra1=,tra2=;
scanf("%d%d",&tra1,&tra2);
addedge(tra1,tra2),addedge(tra2,tra1);
n=max(n,tra1),n=max(n,tra2);
} root = ;
tarjan(); for(int i=;i<=n;i++) {
if( vis[i] || cv[i] ) continue;
color ++ ;
CUT = NUM = ;
dfs(i);
if( CUT == ) {
ans2*=(NUM - ) * NUM /;
ans1 += ;
}
if( CUT == ) {
ans2 *= NUM ;
ans1 += ;
}
if( CUT >= ) {
continue ;
}
}
++SDF;
cout<<"Case "<<SDF<<": ";
cout<<ans1<<" "<<ans2<<endl;
}
return ;
}
TAG : SIN_XIII ⑨
洛谷P3225 HNOI2012 矿场搭建的更多相关文章
- 洛谷 P3225 [HNOI2012]矿场搭建 解题报告
P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...
- 洛谷——P3225 [HNOI2012]矿场搭建
P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...
- 洛谷 P3225 [HNOI2012]矿场搭建
传送门 题目大意:建设几个出口,使得图上无论哪个点被破坏,都可以与出口联通. 题解:tarjian求割点 首先出口不能建在割点上,找出割点,图就被分成了几个联通块. 每个联通块,建出口.如果割点数为0 ...
- 洛谷—— P3225 [HNOI2012]矿场搭建
https://www.luogu.org/problem/show?pid=3225 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有 ...
- BZOJ2730或洛谷3225 [HNOI2012]矿场搭建
BZOJ原题链接 洛谷原题链接 显然在一个点双连通分量里,无论是哪一个挖煤点倒塌,其余挖煤点就可以互相到达,而对于一个点双连通分量来说,与外界的联系全看割点,所以我们先用\(tarjan\)求出点双连 ...
- P3225 [HNOI2012]矿场搭建 割点 tarjan 双联通分量
https://www.luogu.org/problemnew/show/P3225 题意 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条 ...
- P3225 [HNOI2012]矿场搭建 题解
这道题挺难的,可以加深对割点的理解,还有,排列组合好重要了,分连通块,然后乘法原理(加法原理计数什么的) 传送门 https://www.luogu.org/problem/P3225 省选oi题 ...
- P3225 [HNOI2012]矿场搭建
传送门 对于一个点双联通分量,如果它连接了两个或更多割点 那么不论哪个点GG都有至少一条路通到其他的点双联通分量,所以我们不用考虑 如果它只连接一个割点,如果这个割点GG,那整个块也一起GG,所以要再 ...
- [Luogu] P3225 [HNOI2012]矿场搭建
题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之 ...
随机推荐
- Python学习之高级数组(一)
1.Python基础学习之高级数组(一) 1.1视图:就是与较大数组共享相同数据的较小数组.Numpy包提供数据视图的概念是为了精确地控制内存的使用方式. 数组视图.切片视图.转置和重塑视图等 数组 ...
- Python记录14:面向对象编程 类和对象
'''现在主流的编程思想有两种,一种是面向对象,一种是面向过程面向过程编程 核心是过程二字,过程指的是解决问题的步骤,即先干什么.再干什么.最后干什么... 基于该思想编写程序就好比再设计一条流水线, ...
- mysql误删root
在Linux中有时安装Mysql会出现没有root用户的状况,或者说root账户被从mysql.user表中误删除,这样就导致很多权限无法控制.解决办法是重新创建root用户,并授予所有权限,具体方法 ...
- html5 p1练习1,移动页面,标准标签布局
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- Centos 编译 安装 criu
下载依赖库 sudo yum install protobuf protobuf-c protobuf-c-devel protobuf-compiler protobuf-devel protobu ...
- 第八节 JS运动基础
运动基础 让Div运动起来 速度——物体运动的快慢 运动中的Bug 不会停止 速度取某些值会无法停止 到达位置后再点击还会运动 重复点击速度加快 匀速运动(速度不变) 运动框架及应用: 运动框架: 在 ...
- HTTP长连接、短连接究竟是什么?
1. HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接.HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议. IP协议主要解决网络路由和寻址 ...
- 深度解析vuex
1.什么是vuex? vuex 是一个专为 Vue.js 应用程序开发的状态管理模式(通俗一点的说Vuex就是存储数据的工具,类似于cookie.sessionStorage.localStorage ...
- MyBio小隐本记注册破解
既然开始了,就把这一个系列的都破了算了,这次主角小隐本记MyBio 和WDTP的原理是差不多的,先把软件界面换成e文,然后写了15个记录后提示注册,一样的路子,直接跳过注册窗口的弹出就好了 然后查壳一 ...
- 【ASP.NET】 Config Error: This configuration section cannot be used at this path.
Config Error: This configuration section cannot be used at this path. This happens when the section ...