C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建
最近在学图论相关的内容,阅读这篇博客的前提是你已经基本了解了Tarjan求点双。

由割点的定义(删去这个点就可使这个图不连通)我们可以知道,坍塌的挖煤点只有在割点上才会使这个图不连通,而除了割点的其他点上则无可厚非,所以我们只需要考虑这个图的割点的情况。
那么我们就可以求出所有的点双连通分量, 如果这个点双仅有一个割点,那么这个割点坍塌后这个点双就被“孤立”了,所以需要在这个点双里设置一个救援出口。
那么这个点双如果包含多个割点呢?假设它的其中一个割点坍塌了,它还可以从另外几个割点出去。
所以我们只需要判断有几个点双只有一个割点,便是我们要设置的救援出口的数量。
有的同学可能要问了,如果所有点双都有多个割点呢?这种情况是不存在的,因为如果这样所有点双都变得联通了,也就不存在点双了。
关于方案的总数,只需要运用乘法原理。需要注意的是如果整个图就是一个点双,那么救援出口应该是两个,方案数是节点数\(n\),\(n*(n-1)/2\)。
代码
#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
#include <cstdio>
using namespace std;
#define N 510
#define LL long long
LL vis[N],ans1,ans2=1,bcc[N],n,m,num,cntd,DFN[N],IsCut[N],low[N],belong[N];
vector <LL> G[N];
vector <LL> vecd[N];
struct edge {
int u,v;
edge() {};
edge(int U,int V) {u=U;v=V;}
};
stack <edge> st;
LL read() {
LL f=1,s=0;char a=getchar();
while(!(a>='0'&&a<='9')) { if(a=='-') f=-1 ; a=getchar(); }
while(a>='0'&&a<='9') { s=s*10+a-'0'; a=getchar();}
return f*s;
}
void init() {
memset(bcc,0,sizeof(bcc));
memset(DFN,0,sizeof(DFN));
memset(vis,0,sizeof(vis));
memset(IsCut,0,sizeof(IsCut));
memset(belong,0,sizeof(belong));
memset(low,0,sizeof(low));
for(int i=1;i<=N;i++) G[i].clear(),vecd[i].clear();
for(LL i=1,u,v;i<=m;i++) {
u=read();v=read();
vis[u]=vis[v]=1;
G[u].push_back(v);
G[v].push_back(u);
}
ans1=cntd=0;
ans2=1;
}
void Tarjan(LL u,LL fa) {
LL child=0;
DFN[u]=low[u]=++num;
for(LL i=0;i<G[u].size();i++) {
LL v=G[u][i];
if(!DFN[v]) {
child++;
st.push( edge(u,v) );
Tarjan(v,u);
if(low[v]>=DFN[u]) {
IsCut[u]=1;
cntd++;
for(;;) {
edge x=st.top();st.pop();
if(belong[x.u] != cntd) {vecd[cntd].push_back(x.u); belong[x.u] = cntd;}
if(belong[x.v] != cntd) {vecd[cntd].push_back(x.v); belong[x.v] = cntd;}
if(x.u == u && x.v == v) break;
}
}
low[u]=min(low[u],low[v]);
}
else if(DFN[u]>DFN[v] && v!=fa)
low[u]=min(low[u],DFN[v]);
}
if(fa<0 && child==1)
IsCut[u]=0;
}
int main() {
int flag=0;
while(cin>>m && m) {
init();
flag++;
for(int i=1;vis[i];i++)
if(!DFN[i])
Tarjan(i,-1);
for(LL i=1;i<=cntd;i++) {
for(int j=0;j<vecd[i].size();j++)
if(IsCut[vecd[i][j]]) bcc[i]++;//bcc统计第i个点双的割点数量
if(bcc[i]==1){ //仅有一个割点,统计答案
ans1++;
ans2*=(vecd[i].size()-1);//乘法原理
}
}
LL siz=vecd[1].size();
if(!ans1) cout<<"Case "<<flag<<": "<<"2"<<' '<<siz*(siz-1)/2<<endl;//特判原图是不是点双
else cout<<"Case "<<flag<<": "<<ans1<<' '<<ans2<<endl;
}
}
C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建的更多相关文章
- hdu 2460(tarjan求边双连通分量+LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2460 思路:题目的意思是要求在原图中加边后桥的数量,首先我们可以通过Tarjan求边双连通分量,对于边 ...
- [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分)
[Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分) 题面 给出一个无向图,以及q条有向路径.问是否存在一种给边定向的方案,使得 ...
- Tarjan求点双连通分量
概述 在一个无向图中,若任意两点间至少存在两条“点不重复”的路径,则说这个图是点双连通的(简称双连通,biconnected) 在一个无向图中,点双连通的极大子图称为点双连通分量(简称双连通分量,Bi ...
- BZOJ2730或洛谷3225 [HNOI2012]矿场搭建
BZOJ原题链接 洛谷原题链接 显然在一个点双连通分量里,无论是哪一个挖煤点倒塌,其余挖煤点就可以互相到达,而对于一个点双连通分量来说,与外界的联系全看割点,所以我们先用\(tarjan\)求出点双连 ...
- Tarjan 点双+割点+DFS【洛谷P3225】 [HNOI2012]矿场搭建
P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...
- 【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3230 Solved: 1540[Submit][Stat ...
- [BZOJ2730][HNOI2012]矿场搭建 点双 割点
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2852 Solved: 1344[Submit][Stat ...
- BZOJ 2730: [HNOI2012]矿场搭建( tarjan )
先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...
- 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan
[BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...
随机推荐
- TensorFlow机器学习实战指南之第二章2
TensorFlow实现反向传播 本节先举个简单的回归算法的例子.这里先举一个简单的例子,从均值1,标准差为0.1的正态分布中随机抽样100个数,然后乘以变量A,损失函数L2正则函数,也就是实现函数X ...
- grandson定理
用处:求解同余线性方程组 inv:逆元 一堆物品 3个3个分剩2个 5个5个分剩3个 7个7个分剩2个 问这个物品有多少个 5*7*inv(5*7, 3) % 3 = 1 3*7*inv(3*7 ...
- pipeline语法学习日记
1.pipeline 整合job的通用代码,比较基本 2.pipeline参数化构建
- Linux openssh8.0p1升级步骤
前期准备开启本机telnet服务,以防openssh升级失败无法连接服务器.注:redhat 5 6 和 redhat7 开机启动配置相关文件不同,请注意 1.安装zlibtar -xzvf zlib ...
- Cannot find the declaration of element 'ehcache'.
ehchahe.xml中报错: Cannot find the declaration of element 'ehcache'. 由于 <?xml version="1.0" ...
- Git回滚到指定的commit
查看历史commint $ git log (可以记下sha码) 回退命令: $ git reset --hard HEAD^ 回退到上个版本$ git reset --hard HEAD~3 回退到 ...
- js倒计时功能中newData().getTime()在iOS下会报错,显示 nan
最近在做移动端项目 ,有个设置开始时间和结束时间,然后倒计时 这个活动还有几天.在安卓上能正确转换时间,但在iOS上不能显示,为NaN-NaN1-NaN Invalid Date, 就好比new D ...
- HDU-4280-Island Transport(网络流,最大流, ISAP)
链接: https://vjudge.net/problem/HDU-4280 题意: In the vast waters far far away, there are many islands. ...
- 046:ORM模型介绍
ORM模型介绍: 随着项目越来越大,采用写原生SQL的方式在代码中会出现大量的SQL语句,那么问题就出现了: 1.SQL语句重复利用率不高,越复杂的SQL语句条件越多,代码越长.会出现很多相近的SQL ...
- 【bzoj3262】陌上花开
题目描述: 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa& ...