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. docker-compose单服务器部署ELK

    docker-compose 部署ELK 本项目采用的ELK版本为6.5.3,7.0+ 以上的版本部分配置不适合,请查看docker-compose多服务器部署ELK文章 目录结构 elk |--do ...

  2. 自然语言处理 Paddle NLP - 基于预训练模型完成实体关系抽取

    自然语言处理 Paddle NLP - 信息抽取技术及应用 重点:SOP 图.BCEWithLogitsLoss 基于预训练模型完成实体关系抽取 信息抽取旨在从非结构化自然语言文本中提取结构化知识,如 ...

  3. 老生常谈:值类型 V.S. 引用类型

    我在面试的时候经常会问一个问题:"谈谈值类型和引用的区别".对于这个问题,绝大部分人都只会给我两个简洁的答案:"值类型分配在栈中,引用类型分配在堆中",&quo ...

  4. springboot自定义消息转换器

    import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; im ...

  5. 【调制解调】ISB 独立边带调幅

    说明 学习数字信号处理算法时整理的学习笔记.同系列文章目录可见 <DSP 学习之路>目录,代码已上传到 Github - ModulationAndDemodulation.本篇介绍 IS ...

  6. 开发自己的Prometheus Exporter、实现自定义指标

    Prometheus Exporter基础知识 Prometheus Exporter的概念.工作原理  Prometheus Exporter是一个用来收集和暴露指标数据的工具,通过与Prometh ...

  7. Vue-treeselect 实现下拉树懒加载,末节点不要箭头

    项目需要,可选择的下拉树,由于数据过多,显示要有层级感,所以使用了懒加载模式 vue-treeselect官网:https://www.vue-treeselect.cn/ 1.前端代码 1.下载依赖 ...

  8. shell: xscp

    #!/bin/bash ips=( 1.1.1.1 1.1.1.2 ) user= passwd= for i in ${ips[@]} do echo "== $i ==" ss ...

  9. 【技术积累】Linux中的命令行【理论篇】【四】

    ar命令 命令介绍 ar命令是Linux系统中的一个工具,用于创建.修改和提取静态库文件(archive files).静态库文件是一组已编译的目标文件的集合,可以被链接到可执行文件中. 命令说明 a ...

  10. 一键部署 Umami 统计个人网站访问数据

    谈到网站统计,大家第一时间想到的肯定是 Google Analytics.然而,我们都知道 Google Analytics 会收集所有用户的信息,对数据没有任何控制和隐私保护. Google Ana ...