the description of problem

(我看的是 PDF 里面的原题所以这里描述会和题目不一样,但是大意一致)

给定一个未必连通的无向图,问最少在几个点设置出口,可以保证任意一个点坍塌后,工人们仍然可以从出口逃生,同时问设置最少出口的方案数量。

thoughts & solution

我们可以知道每个连通块之间是相互独立的,对于每个连通块间的答案,是互不影响的,所以说每个连通块之间的答案是要靠乘法原理维护。

(下面都用 \(res\) 来记录我们需要设置的出口数量,\(num\) 来表示我们总共的方案数)

这个时候我们考虑每个连通块:

  1. 如果这个连通块中没有割点,这个时候我们只需要在这个连通块内部随意放置两个出口就可以保证每个点都能到达出口。我们还需要分类讨论:

    • 如果这个连通块内只有一个点,我们的答案就将变成
      \[res \gets res + 1
      \]
    • 我们这个时候记录答案就是(记这个连通块内部有 \(cnt\) 个点)
      \[res \gets res + 2, num \gets num * C_{cnt} ^ {2}
      \]
  2. 如果这个连通块中只有一个割点,我们需要对它进行一个缩点的操作,这个时候,我们的一个割点会一分为二,分别到它这个割点所连接的两个连通分量中,这个时候我们只需要保证里面有一个出口就行了,方案数则是这个左右两个分量中个自得数量(记为 \(cnt\))

\[res \gets res + 1, num \gets (cnt - 1) * num
\]
  1. 如果这个连通块有两个或两个以上得割点,我们这个时候则可以证明它一定能去往别得连通块,所以说不会对结果造成贡献。证明放在后面。

Proof

  1. 如果在割点坍塌,在缩完点之后必定是一棵树,而且我们在每一个之前只有一个割点的连通图里面放置了一个出口,所以,在这棵树的最下面必定会有叶子节点,这个叶子节点就会救活这棵树。

  2. 如果是连接了一个割点的 V-DCC 坍塌某一个点,我们在删除这个坍塌的点之后,我们这个图还是连通的,而且因为这个图上面还有一个割点,我们就可以通过这个割点走向另外一个安全的出口。

  3. 如果是连接了两个割点的 V-DCC 坍塌了某一个点,我们同样可以让这个图里面的点去到其他出口。

综上,证毕

CODE TIME

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rl register ll const ll N = 5e4 + 10, M = 1e5 + 10; ll n, m; ll tot, ne[M], e[M], h[N]; ll dfn[N], low[N], timestamp; ll stk[N], top, dcc_cnt, root; vector<ll> dcc[N]; bool cut[N]; inline void add(ll a, ll b)
{
ne[++tot] = h[a], h[a] = tot, e[tot] = b;
} inline void tarjan(ll u)
{
dfn[u] = low[u] = ++ timestamp;
stk[ ++ top] = u; if(root == u && h[u] == -1)
{
dcc_cnt ++, dcc[dcc_cnt].push_back(u);
return ;
} ll cnt = 0;
for(rl i=h[u]; ~i; i = ne[i])
{
ll v = e[i];
if(!dfn[v])
{
tarjan(v), low[u] = min(low[u], low[v]);
if(dfn[u] <= low[v])
{
cnt ++;
if(u != root || cnt > 1) cut[u] = true;
++ dcc_cnt;
ll ele;
do {
ele = stk[top --];
dcc[dcc_cnt].push_back(ele);
} while(ele != v);
dcc[dcc_cnt].push_back(u);
}
}
else low[u] = min(low[u], dfn[v]);
}
} int main()
{
ll T = 1;
while(cin >> m, m)
{
for(rl i=1; i <= dcc_cnt; ++ i) dcc[i].clear();
tot = n = timestamp = top = dcc_cnt = 0;
memset(h, -1, sizeof h), memset(dfn, 0, sizeof dfn), memset(cut, 0, sizeof cut); while(m -- )
{
ll a, b;
cin >> a >> b;
n = max(n, a), n = max(n, b);
add(a, b), add(b, a);
} for(root = 1; root <= n; ++ root)
if(!dfn[root])
tarjan(root); ll res = 0, num = 1; for(rl i=1; i <= dcc_cnt; ++ i)
{
ll cnt = 0;
for(rl j : dcc[i])
if(cut[j])
cnt ++ ; if(cnt == 0)
{
if(dcc[i].size() > 1) res += 2, num *= dcc[i].size() * (dcc[i].size() - 1) / 2;
else res ++ ;
}
else if(cnt == 1) res ++, num *= dcc[i].size()- 1;
} printf("Case %lld: %lld %lld\n", T ++, res, num);
}
return 0;
}

the solution of Mining Your Own Business的更多相关文章

  1. UVALive - 5135 - Mining Your Own Business(双连通分量+思维)

    Problem   UVALive - 5135 - Mining Your Own Business Time Limit: 5000 mSec Problem Description John D ...

  2. HDU3844 Mining Your Own Business

    HDU3844 Mining Your Own Business 问题描述John Digger是一个大型illudium phosdex矿的所有者.该矿山由一系列隧道组成,这些隧道在各个大型交叉口相 ...

  3. 「题解报告」SP16185 Mining your own business

    题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...

  4. UVA5135 Mining Your Own Business ( 无向图双连通分量)

    题目链接 题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太 ...

  5. HDU 3844 Mining Your Own Business

    首先,如果图本来就是一个点双联通的(即不存在割点),那么从这个图中选出任意两个点就OK了. 如果这个图存在割点,那么我们把割点拿掉后图就会变得支离破碎了.对于那种只和一个割点相连的块,这个块中至少要选 ...

  6. LA 5135 Mining Your Own Business

    求出 bcc 后再……根据大白书上的思路即可. 然后我用的是自定义的 stack 类模板: #include<cstdio> #include<cstring> #includ ...

  7. UVA 1108 - Mining Your Own Business

    刘汝佳书上都给出了完整的代码 在这里理一下思路: 由题意知肯定存在一个或者多个双连通分量: 假设某一个双连通分量有割顶.那太平井一定不能打在割顶上. 而是选择割顶之外的随意一个点: 假设没有割顶,则要 ...

  8. HDU 3844 Mining Your Own Business(割点,经典)

    题意: 给出一个连通图,要求将某些点涂黑,使得无论哪个点(包括相关的边)撤掉后能够成功使得剩下的所有点能够到达任意一个涂黑的点,颜料不多,涂黑的点越少越好,并输出要涂几个点和有多少种涂法. 思路: 要 ...

  9. UVALive - 5135 Mining Your Own Business

    刘汝佳白书上面的一道题目:题意是给定一个联通分量,求出割顶以及双连通分量的个数,并且要求出安放安全井的种类数,也就是每个双连通分量中结点数(除开 割顶)个数相乘,对于有2个及以上割顶的双连通分量可以不 ...

  10. UVALive 5135 Mining Your Own Business 双连通分量 2011final

    题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太平井逃脱, ...

随机推荐

  1. 一文了解Go语言的函数

    1. 引言 函数是编程中不可或缺的组成部分,无论是在Go语言还是其他编程语言中,函数都扮演着重要的角色.函数能够将一系列的操作封装在一起,使得代码更加模块化.可重用和易于维护. 在本文中,我们将详细介 ...

  2. 使用ansible-app2k8s管理和部署服务到 kubernetes

    ansible-app2k8s #1 介绍 使用 ansible 管理和部署服务到 kubernetes 适用于项目容器化,多套 k8s 环境的管理,可结合CICD工具做DevOps 来自于项目实践, ...

  3. 6个常见的IB网络不通问题

    摘要:如果遇到IB网络不通,可以试着从高层往底层逐步分析看看. 本文分享自华为云社区<常见IB网络不通问题记录>,作者: tsjsdbd . 如果遇到IB网络不通,可以试着从高层往底层逐步 ...

  4. linux 服务器上如何判断网络是否开通

      项目上由于升级了kafka需要测试下网络是否是通的,因此需要使用命令 nc -zv ip地址 端口这个命令来跑一下网络是否是通的,最后发现是新的kafka的config使用了新的端口,没有开通网络 ...

  5. Linux网络设备命名规则简介

    Linux网络设备命名规则简介 几年前, Linux内核为网络接口分配名称采用的是一种简单和直观的方式:一个固定的前缀和一个递增的序号.比如,内核使用eth0名称以标识启动后第一个加载的网络设备,第二 ...

  6. Day02_Java_作业

    A:选择题 1. 若有定义:int a,b; a=a+10;则执行上述语句后,a的值是(d). A. 10 B. 11 C. 0 D. 编译产生错误 2. 以下选项中变量均已正确定义,合法的赋值语句是 ...

  7. gin 接口开发 - 用户输入自动 TrimSpace

    最近在思考一个问题,针对用户的输入,能不能快速校验? 比方说下面的 struct,大家用过 gin 的就知道,支持指定某个字段为 required,用户如果不输入,就检验不通过. type Login ...

  8. 为什么Python是数据科学家的首选语言

    这篇文章全面探讨了Python作为数据科学领域首选语言的原因.从Python的历史.特性,到在数据科学中的应用实例,再到与其他数据科学语言的比较,以及在实际企业中的应用,我们深入剖析了Python的优 ...

  9. linux top中 VSS,RSS,PSS,USS 4个字段的解读

    参考文章:linux中top命令 VSS,RSS,PSS,USS 四个内存字段的解读

  10. docker 镜像与容器存储目录结构

    目录列表及大小示例-20220314 root@dewan01:/var/lib/docker# du -sh * 88K buildkit 72K containers 884K image 60K ...