刘汝佳书上都给出了完整的代码

在这里理一下思路:

由题意知肯定存在一个或者多个双连通分量;

假设某一个双连通分量有割顶。那太平井一定不能打在割顶上。

而是选择割顶之外的随意一个点;

假设没有割顶,则要在该双连通分量上打两个井

至于打井方案。见代码

#include <cstdio>
#include <cstring>
#include <vector>
#include <stack>
#include <map>
using namespace std; const int N = 50005; struct Edge {
int u, v;
Edge() {}
Edge(int u, int v) {
this->u = u;
this->v = v;
}
}; int pre[N], bccno[N], dfs_clock, bcc_cnt;
bool iscut[N]; vector<int> g[N], bcc[N];
stack<Edge> S; int dfs_bcc(int u, int fa) {
int lowu = pre[u] = ++dfs_clock;
int child = 0;
for (int i = 0; i < g[u].size(); i++) {
int v = g[u][i];
Edge e = Edge(u, v);
if (!pre[v]) {
S.push(e);
child++;
int lowv = dfs_bcc(v, u);
lowu = min(lowu, lowv);
if (lowv >= pre[u]) {
iscut[u] = true;
bcc_cnt++; bcc[bcc_cnt].clear(); //start from 1
while(1) {
Edge x = S.top(); S.pop();
if (bccno[x.u] != bcc_cnt) {bcc[bcc_cnt].push_back(x.u); bccno[x.u] = bcc_cnt;}
if (bccno[x.v] != bcc_cnt) {bcc[bcc_cnt].push_back(x.v); bccno[x.v] = bcc_cnt;}
if (x.u == u && x.v == v) break;
}
}
} else if (pre[v] < pre[u] && v != fa) {
S.push(e);
lowu = min(lowu, pre[v]);
}
}
if (fa < 0 && child == 1) iscut[u] = false;
return lowu;
} int st; void find_bcc() {
memset(pre, 0, sizeof(pre));
memset(iscut, 0, sizeof(iscut));
memset(bccno, 0, sizeof(bccno));
dfs_clock = bcc_cnt = 0;
dfs_bcc(0, -1);
} int n, m; typedef long long ll; void solve() {
ll ans1 = 0, ans2 = 1;
for (int i = 1; i <= bcc_cnt; i++) {
int cut_cnt = 0;
for (int j = 0; j < bcc[i].size(); j++)
if (iscut[bcc[i][j]]) cut_cnt++;
if (cut_cnt == 1) {
ans1++;
ans2 *= (ll)(bcc[i].size() - cut_cnt);
}
}
if (bcc_cnt == 1) {
ans1 = 2;
ans2 = (ll)bcc[1].size() * (bcc[1].size() - 1) / 2;
}
printf(" %lld %lld\n", ans1, ans2);
} int main() {
int cas = 0;
while (~scanf("%d", &m) && m) {
int u, v, Max = 0;
while (m--) {
scanf("%d%d", &u, &v);
u--; v--;
g[u].push_back(v);
g[v].push_back(u);
Max = max(Max, u);
Max = max(Max, v);
}
find_bcc();
printf("Case %d:", ++cas);
solve();
for (int i = 0; i <= Max; i++)
g[i].clear();
}
return 0;
}

UVA 1108 - 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. HDU 3844 Mining Your Own Business(割点,经典)

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

  8. UVALive - 5135 Mining Your Own Business

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

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

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

随机推荐

  1. JS 中document.URL 和 window.location.href 的区别

    实际上,document 和 window 这两个对象的区别已经包含了这个问题的答案. document 表示的是一个文档对象,window 表示一个窗口对象. 一个窗口下面可以有很多的documen ...

  2. 可以用google了

    半年都上不了google,现在可以了, 哈哈,支持自动更新, 有时候用google还是很不错的,尤其是英文搜索.

  3. poj 3270(置换群)

    题意:给定n头母牛的脾气大小,然后让你通过交换任意两头母牛的位置使得最后的母牛序列的脾气值从小到大,交换两头母牛的代价是两个脾气之和,使得代价最小. 分析:以前做过一道题,只有一个地方和这道题不同,但 ...

  4. codeforces 340B Maximal Area Quadrilateral(叉积)

    事实再一次证明:本小菜在计算几何上就是个渣= = 题意:平面上n个点(n<=300),问任意四个点组成的四边形(保证四条边不相交)的最大面积是多少. 分析: 1.第一思路是枚举四个点,以O(n4 ...

  5. PHP开发规范

    十.开发规范下面我们讲解 Yii 编程中推荐的开发规范.为简单起见,我们假设 WebRoot 是 Yii 应用安装的目录.1.URL默认情况下,Yii 识别如下格式的 URL: http://host ...

  6. C++ 虚拟继承

    1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念.虚拟基类是为解决多重继承而出现的.如:类D继承自类B1.B2,而类B1.B2都继 承自类A,因此在类D中两次出现类A中的变量和函数.为了节省内 ...

  7. sql server 数据库的操作

    Technorati 标记: sql截取,sql修改 把一个字段的部分取出来,插入到新字段 1 )  //方法二 sql server修改一个字段中的部分数据  update tablename se ...

  8. Nodejs_day03

    1.Stream (流) Stream有四种流类型 1.Readable - 可读操作 2.Writable - 可写操作 3.Duplex - 可读可写操作 4.Transform - 操作被写入数 ...

  9. 【LeetCode】202 - Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

  10. c语言的几个重要知识点

      内存结构 这是核心中的核心,请仔细看完,充分理解,否则请不要看下一节内容. 每个程序一启动都有一个大小为4GB的内存,这个内存叫虚拟内存,是概念上的,真正能用到的,只是很小一部分,一般也就是在几百 ...