题意

煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。

请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。

思路

找出图中的割点,利用tarjan, 然后对非割点的联通块dfs。

找出一个块中直接相邻的割点个数。
如果个数为0,说明不能通过割点出逃,所以要在这个联通块中选两个点作为出口。
如果个数为1,要另找一个出口,以防割点被堵住。
如果个数>=2, 就不用了,从割点出逃就行了。

#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> /* ⊂_ヽ
  \\ Λ_Λ 来了老弟
   \('ㅅ')
    > ⌒ヽ
   /   へ\
   /  / \\
   レ ノ   ヽ_つ
  / /
  / /|
 ( (ヽ
 | |、\
 | 丿 \ ⌒)
 | |  ) /
'ノ )  Lノ */ using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define boost ios::sync_with_stdio(false);cin.tie(0)
#define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c); const ll oo = 1ll<<;
const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e9+;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} inline void cmax(int &x,int y){if(x<y)x=y;}
inline void cmax(ll &x,ll y){if(x<y)x=y;}
inline void cmin(int &x,int y){if(x>y)x=y;}
inline void cmin(ll &x,ll y){if(x>y)x=y;} /*-----------------------showtime----------------------*/ const int maxn = ;
struct E{
int v,nxt;
}edge[maxn*maxn];
int head[maxn],gtot=;
void addedge(int u,int v){
edge[gtot].v = v;
edge[gtot].nxt = head[u];
head[u] = gtot++;
}
int dfn[maxn],low[maxn],cnt = ;
int cut[maxn];
int rt,rs;
void tarjan(int u,int fa){
dfn[u] = low[u] = ++cnt;
for(int i=head[u]; ~i; i = edge[i].nxt){
int v = edge[i].v;
if(!dfn[v]){
tarjan(v,u);
low[u] = min(low[u], low[v]);
if(low[v] >= dfn[u]){
if(u == rt) {
rs++;
}
else cut[u] = ;
}
}
else if(v != fa){
low[u] = min(low[u], dfn[v]);
}
}
} int vis[maxn],mark = ;
int num,ge_num;
void dfs(int u){
vis[u] = mark;
num++;
for(int i=head[u]; ~i; i = edge[i].nxt){
int v = edge[i].v;
if(cut[v] && vis[v] < mark){
vis[v] = mark;
ge_num++;
}
else if(!vis[v]){
dfs(v);
}
} }
int main(){
int m,n,cas=;
while(~scanf("%d", &m) && m) {
memset(head, -, sizeof(head));
gtot = ;cnt=;
n = ;
for(int i=; i<=m; i++) {
int x,y; scanf("%d%d", &x, &y);
addedge(x, y);
addedge(y, x);
n = max(n, x);
n = max(n, y);
}
memset(dfn, , sizeof(dfn));
memset(low, ,sizeof(low));
memset(cut, , sizeof(cut)); for(int i=; i<=n; i++) {
if(dfn[i] == ) {
rt = i;
rs = ;
tarjan(i, -);
if(rs >= ) cut[rt] = true;
}
} int ans1 = ;
ll ans2 = ;
mark = ;
memset(vis, , sizeof(vis));
for(int i=; i<=n; i++){
if(!vis[i] && !cut[i]){ num = ;
ge_num = ;
++mark;
dfs(i); if(ge_num == ){
ans1 += ;
ans2 *= 1ll*(num-)*num/;
}
else if(ge_num == ){
ans1 += ;
ans2 *= num;
}
}
}
printf("Case %d: %d %lld\n",++cas, ans1, ans2);
} return ;
}

P3225 [HNOI2012]矿场搭建 割点 tarjan 双联通分量的更多相关文章

  1. BZOJ_2730_ [HNOI2012]矿场搭建_点双联通分量

    BZOJ_2730_ [HNOI2012]矿场搭建_点双联通分量 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路 ...

  2. P3225 [HNOI2012]矿场搭建[割点]

    题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之 ...

  3. 洛谷 P3225 [HNOI2012]矿场搭建 解题报告

    P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...

  4. 洛谷——P3225 [HNOI2012]矿场搭建

    P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...

  5. 【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3230  Solved: 1540[Submit][Stat ...

  6. 洛谷P3225 HNOI2012 矿场搭建

    题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之 ...

  7. P3225 [HNOI2012]矿场搭建

    传送门 对于一个点双联通分量,如果它连接了两个或更多割点 那么不论哪个点GG都有至少一条路通到其他的点双联通分量,所以我们不用考虑 如果它只连接一个割点,如果这个割点GG,那整个块也一起GG,所以要再 ...

  8. [Luogu] P3225 [HNOI2012]矿场搭建

    题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之 ...

  9. 洛谷—— P3225 [HNOI2012]矿场搭建

    https://www.luogu.org/problem/show?pid=3225 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有 ...

随机推荐

  1. springboot整合elasticsearch(基于es7.2和官方high level client)

    前言 最近写的一个个人项目(传送门:全终端云书签)中需要用到全文检索功能,目前 mysql,es 都可以做全文检索,mysql 胜在配置方便很快就能搞定上线(参考这里),不考虑上手难度,es 在全文检 ...

  2. 最近很火的MySQL:抛开复杂的架构设计,MySQL优化思想基本都在这

    优化一览图 优化 笔者将优化分为了两大类:软优化和硬优化.软优化一般是操作数据库即可:而硬优化则是操作服务器硬件及参数设置. 1.软优化 1)查询语句优化 首先我们可以用EXPLAIN或DESCRIB ...

  3. Django使用本机IP无法访问,使用127.0.0.1能正常访问

    使用Django搭建web站点后,使用127.0.0.1能访问,但是用自己本机IP却无法访问. 我们先到Django项目中找到setting文件 找到——> ALLOWED_HOSTS = [] ...

  4. .NET Core 3.0预览版7中的ASP.NET Core和Blazor更新

    .NET Core 3.0 Preview 7现已推出,它包含一系列ASP.NET Core和Blazor的新更新. 以下是此预览中的新功能列表: 最新的Visual Studio预览包括.NET C ...

  5. 一文速览Vue全栈

    一文速览Vue全栈 原创: 新哥Lewis 天道酬勤Lewis 7月7日 Vue 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用,专注于声明式渲染视图 ...

  6. 算法与数据结构基础 - 二叉树(Binary Tree)

    二叉树基础 满足这样性质的树称为二叉树:空树或节点最多有两个子树,称为左子树.右子树, 左右子树节点同样最多有两个子树. 二叉树是递归定义的,因而常用递归/DFS的思想处理二叉树相关问题,例如Leet ...

  7. imageloader+图片压缩

    public class MainActivity extends AppCompatActivity { private ImageView ivIcon; @Override protected ...

  8. Simple Windows Service in C++

    本文是来自CodeProject中的一篇名为Simple Windows Service in C++的译文,原文地址为:https://www.codeproject.com/Articles/49 ...

  9. 垂直渐变的Button

    public partial class RoundButton : Button { Rectangle r; private Brush _myBrush = null; , , ); , , ) ...

  10. 解决php - Laravel rules preg_match(): No ending delimiter '/' found 问题

    ### 说明解决php - Laravel preg_match(): No ending delimiter '/' found 一.遇到问题的原因本正常添加如下 public function r ...