题意:

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

思路:

  要使得任意撤掉一个点都能使其他点能够到达黑点,那么点双连通分量能保证这点,那么就在同个点双连通分量内涂黑1个点。但是每个【点双连通分量】都涂吗?太浪费颜料了,那就缩点成树,只需要涂叶子即可,那就找度为1的缩点。但是种数呢?叶子内的点除了割点外都是可以涂黑的,因为如果黑色割点被撤掉,那么叶子中的其他点怎么办?所以不能涂割点,每个黑点有【叶子中的点数-1】种涂法,所有黑店的涂法相乘为第2个结果。

  特殊情况,因为给的是连通图且至少有2个点,那么还可能会出现没有割点的情况(仅1个点双连通分量),那就直接涂黑两个,以防一个黑点被撤掉。

  此题出现的连续的点可能多达10万个,DFS就会爆栈。在C++下可以手动开栈,G++下的还不清楚怎么开。

 #pragma comment(linker,"/STACK:102400000,102400000")//开栈
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <stack>
#define LL long long
#define pii pair<int,int>
using namespace std;
const int N=+;
const int INF=0x7f7f7f7f;
int up;
int low[N], dfn[N];
bool iscut[N];
int dfn_clock, bcc_cnt, bcc_no[N];
unordered_map<int,int> mapp;
stack< pii > stac;
vector<int> bcc[N], vect[N]; void DFS(int x, int far)//tarjan
{
dfn[x]=low[x]=++dfn_clock; int chd=;
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!dfn[t])
{
chd++;
stac.push(make_pair(x,t));
DFS(t,x);
low[x]=min( low[x], low[t]);
if(low[t]>=dfn[x])
{
iscut[x]=true; //需要标记割点
bcc[++bcc_cnt].clear();
while(true)
{
int a=stac.top().first;
int b=stac.top().second;
stac.pop();
if(bcc_no[a]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(a);
bcc_no[a]=bcc_cnt;
}
if(bcc_no[b]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(b);
bcc_no[b]=bcc_cnt;
}
if(a==x&&b==t) break;
}
}
}
else if( dfn[t]<dfn[x] && t!=far)
{
stac.push(make_pair(x,t));
low[x]=min(low[x],dfn[t]);
}
}
if(chd==&&far==) iscut[x]=false; //根
} void find_bcc(int Case)
{
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(iscut,,sizeof(iscut));
memset(bcc_no,,sizeof(bcc_no)); dfn_clock=bcc_cnt=;
for(int i=; i<=up; i++) if(!dfn[i]) DFS(i,); //深搜
LL ans1=,ans2=; for(int i=; i<=bcc_cnt; i++) //统计度为多少
{
int cnt=;
for(int j=; j<bcc[i].size(); j++) if(iscut[bcc[i][j] ]) cnt++; //有割点就统计连通分量i的度。
if(cnt==) ans1++, ans2*=bcc[i].size()-;
}
if(bcc_cnt==) ans1=,ans2=(LL)bcc[].size()*(bcc[].size()-)/;
printf("Case %d: %lld %lld\n", Case, ans1, ans2);
} int main()
{
freopen("input.txt", "r", stdin);
int a, b, n, j=;
while(scanf("%d",&n), n)
{
mapp.clear();
for(int i=; i<N; i++) vect[i].clear();
up=;
for(int i=; i<n; i++)
{
scanf("%d%d",&a,&b);
if(!mapp[a]) mapp[a]=++up;
if(!mapp[b]) mapp[b]=++up;//点号缩小为连续 vect[mapp[a]].push_back(mapp[b]);
vect[mapp[b]].push_back(mapp[a]);
}
find_bcc(++j);
}
return ;
}

AC代码

HDU 3844 Mining Your Own Business(割点,经典)的更多相关文章

  1. HDU 3844 Mining Your Own Business

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

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

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

  3. HDU3844 Mining Your Own Business

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

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

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

  5. HDU 2181 哈密顿绕行世界问题(经典DFS+回溯)

    哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. HDU 3038 - How Many Answers Are Wrong - [经典带权并查集]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  7. HDU 1789 Doing Homework again(非常经典的贪心)

    Doing Homework again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  8. HDU 1180 诡异的楼梯(超级经典的bfs之一,需多回顾)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1180 诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others)     ...

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

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

随机推荐

  1. C++文件操作之get/getline

    问题描述:                C++ 读取写入文件,其中读取文件使用get和getline方式 参考资料: http://simpleease.blog.163.com/blog/stat ...

  2. 【BZOJ】【1877】【SDOI2009】晨跑

    网络流/费用流 费用流入门题……根本就是模板题好吗! 拆点搞定度数限制,也就是每个点最多经过一次……源点汇点除外. /***************************************** ...

  3. 【锋利的JQuery-学习笔记】Tab选项卡的实现

    效果图: 关键点: 1.标签和标签内容都是用<ul><li>实现的,主要是通过Css样式设计成选项卡的模样. 2.用js代码实现点击标签时,标签内容的切换(做法是<div ...

  4. Chp18: Hard

    18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators. Solut ...

  5. HDU4725 The Shortest Path in Nya Graph SPFA最短路

    典型的最短路问题,但是多了一个条件,就是每个点属于一个layer,相邻的layer移动,如x层移到x+1层需要花费c. 一种显而易见的转化是我把这些边都建出来,但是最后可能会使得边变成O(n^2); ...

  6. java基础知识回顾之java集合类-Properties集合

    /** java.lang.Object   |--java.util.Dictionary<K,V>      |--java.util.Hashtable<Object,Obje ...

  7. mapreduce程序编写(WordCount)

    折腾了半天.终于编写成功了第一个自己的mapreduce程序,并通过打jar包的方式运行起来了. 运行环境: windows 64bit eclipse 64bit jdk6.0 64bit 一.工程 ...

  8. http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html(重要)

    http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html

  9. BZOJ 3720 gty的妹子树

    块状树裸题 块状树: 首先对树进行分块,分出的每一块都是一个连通块 通常的分块的方式如下: 1.父亲所在块不满,分到父亲所在块中 2.父亲所在块满,自己单独开一个块 (貌似有更为优越的分块方式? 注意 ...

  10. SpringMVC学习总结(六)——SpringMVC文件上传例子(2)

    基本的SpringMVC的搭建在我的上一篇文章里已经写过了,这篇文章主要说明一下使用SpringMVC进行表单上的文件上传以及多个文件同时上传的不同方法 一.配置文件: SpringMVC 用的是 的 ...