HDU3844 Mining Your Own Business
HDU3844 Mining Your Own Business
问题描述
John Digger是一个大型illudium phosdex矿的所有者。该矿山由一系列隧道组成,这些隧道在各个大型交叉口相遇。与一些业主不同,Digger实际上关心他的工人的福利,并担心矿山的布局。具体来说,他担心可能会出现一个交汇处,如果发生倒塌,会将矿井的一个区域的工人与其他工人隔离开来(如你所知,illudium phosdex非常不稳定)。为了解决这个问题,他希望从交叉点到地面安装特殊的逃生轴。他可以在每个交叉点安装一个逃生轴,但Digger并不关心他的工人那么多。相反,他想安装最少数量的逃生轴,这样如果任何一个交叉点坍塌,所有在交叉点坍塌中幸存的工人将拥有通往地面的路径。
编写一个程序来计算最小的逃生轴数量以及可以安装这个最小数量的逃生轴的总方式。
输入
输入包含几个测试用例。每种情况的第一行包含正整数N(N <= 5×10 ^ 4),表示矿井隧道的数量。在此之后是N行,每行包含两个不同的整数s和t,其中s和t是结号。连接点从1开始连续编号。每对连接点最多由一个隧道连接。每组矿井隧道形成一个连接单元(也就是说,您可以从任何一个交叉点到达任何其他交叉点)。
最后一个测试用例后面是一个包含单个零的行。
输出
对于每个测试案例,显示其案例编号,然后显示矿井隧道系统所需的最小数量的逃生轴以及这些逃生轴的安装方案数。您可以假设结果适合带符号的64位整数。
题意:给定一个无向连通图,选择一些特殊点,当图中任意一个点(也有可能是特殊点)被删去的时候,其他点至少能到达一个特殊点。
显然我们不会将割点作为特殊点,因为如果割点被去掉,他所在的dcc仍然要有特殊点,而此时割点是没有必要做特殊点的,对于包含两个及以上割点的dcc也是不需要特殊点的,即使一个割点被去掉,这个dcc仍然可以通过其他割点到其他dcc,因此特殊点一定在割点数量为1的dcc内,方案数就很显然了,乘起来就可以了。另外如果整张图是一个dcc,之前的分析就没有用了,此时显然需要2个特殊点,方案数为C(n,2)。另外这个题没有给点的个数,但保证是连续的(不然又要离散化了……),所以可以在输入的时候取max来求得。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define int long long
#define MAXN 100010
#define LL long long
#define ma(x) memset(x,0,sizeof(x))
using namespace std;
struct edge
{
int u,v,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define n(x) ed[x].nxt
#define u2(x) ed2[x].u
#define v2(x) ed2[x].v
#define n2(x) ed2[x].nxt
}ed[MAXN*10],ed2[MAXN*10];
int first[MAXN],num_e;
#define f(x) first[x]
int first2[MAXN],num_e2;
#define f2(x) first2[x] int n,m;
int dfn[MAXN],low[MAXN],num,root;
int stack[MAXN],top,cnt;
bool cut[MAXN];
vector<int> dcc[MAXN];
int c[MAXN],du[MAXN];
void tarjan(int x)
{
dfn[x]=low[x]=++num;
stack[++top]=x;
if(x==root&&!f(x)){dcc[++cnt].push_back(x);return;}
int flag=0;
for(int i=f(x);i;i=n(i))
if(!dfn[v(i)])
{
tarjan(v(i)),low[x]=min(low[v(i)],low[x]);
if(low[v(i)]>=dfn[x])
{
flag++;
if(x!=root||flag>1)cut[x]=1;
cnt++;int z;
do{dcc[cnt].push_back(z=stack[top--]);}while(z!=v(i));
dcc[cnt].push_back(x);
}
}
else low[x]=min(low[x],dfn[v(i)]);
}
void init()
{
ma(first);ma(first2);ma(dfn);ma(low);ma(cut);ma(c);ma(du);ma(dcc);
num_e=num_e2=n=num=top=cnt=0;
}
inline void add(int u,int v);
inline void add2(int u,int v);
signed main()
{
// freopen("in.txt","r",stdin); for(int ooo=1;;ooo++)
{
scanf("%lld",&m);if(!m)break;
init();
printf("Case %lld: ",ooo);
int a,b;
for(int i=1;i<=m;i++)
{
scanf("%lld%lld",&a,&b);
n=max(max(a,b),n);
add(a,b),add(b,a);
}
for(int i=1;i<=n;i++)
if(!dfn[i]){root=i;tarjan(i);}
if(cnt==1){printf("2 %lld\n",n*(n-1)/2);continue;}
num=cnt;
for(int i=1;i<=n;i++)
if(cut[i])c[i]=++num;
for(int i=1;i<=cnt;i++)
for(int j=0;j<dcc[i].size();j++)
{
int x=dcc[i][j];
if(cut[x])add2(i,c[x]),add(c[x],i),du[i]++;
else c[x]=i;
}
int ans=0,fa=1;
for(int i=1;i<=cnt;i++)
if(du[i]==1)
{
ans++;
fa*=dcc[i].size()-1;
}
printf("%lld %lld\n",ans,fa);
}
}
inline void add(int u,int v)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
n(num_e)=f(u);
f(u)=num_e;
}
inline void add2(int u,int v)
{
++num_e2;
u2(num_e2)=u;
v2(num_e2)=v;
n2(num_e2)=f2(u);
f2(u)=num_e2;
}
HDU3844 Mining Your Own Business的更多相关文章
- hdu3844 Mining Your Own Business,无向双连接组件
		点击打开链接 无向图的双连通分量 #include<cstdio> #include<stack> #include<vector> #include<map ... 
- UVALive - 5135 - Mining Your Own Business(双连通分量+思维)
		Problem UVALive - 5135 - Mining Your Own Business Time Limit: 5000 mSec Problem Description John D ... 
- 「题解报告」SP16185 Mining your own business
		题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ... 
- UVA5135 Mining Your Own Business ( 无向图双连通分量)
		题目链接 题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太 ... 
- HDU 3844 Mining Your Own Business
		首先,如果图本来就是一个点双联通的(即不存在割点),那么从这个图中选出任意两个点就OK了. 如果这个图存在割点,那么我们把割点拿掉后图就会变得支离破碎了.对于那种只和一个割点相连的块,这个块中至少要选 ... 
- LA 5135 Mining Your Own Business
		求出 bcc 后再……根据大白书上的思路即可. 然后我用的是自定义的 stack 类模板: #include<cstdio> #include<cstring> #includ ... 
- UVA 1108 - Mining Your Own Business
		刘汝佳书上都给出了完整的代码 在这里理一下思路: 由题意知肯定存在一个或者多个双连通分量: 假设某一个双连通分量有割顶.那太平井一定不能打在割顶上. 而是选择割顶之外的随意一个点: 假设没有割顶,则要 ... 
- HDU 3844 Mining Your Own Business(割点,经典)
		题意: 给出一个连通图,要求将某些点涂黑,使得无论哪个点(包括相关的边)撤掉后能够成功使得剩下的所有点能够到达任意一个涂黑的点,颜料不多,涂黑的点越少越好,并输出要涂几个点和有多少种涂法. 思路: 要 ... 
- UVALive - 5135 Mining Your Own Business
		刘汝佳白书上面的一道题目:题意是给定一个联通分量,求出割顶以及双连通分量的个数,并且要求出安放安全井的种类数,也就是每个双连通分量中结点数(除开 割顶)个数相乘,对于有2个及以上割顶的双连通分量可以不 ... 
随机推荐
- C# WPF 如何禁止窗口拖到屏幕边缘自动最大化
			win7以上的系统新增了功能--窗口拖到屏幕边缘自动最大化 
- netbeans性能分析文件保存位置
			C:\Users\Administrator\AppData\Roaming\NetBeans\8.2\config\HTTPMonitor 分析完,记得把文件删除,不然系统盘要满了 
- Oracle 查询库中所有表名、字段名、表名说明、字段名说明(原创)
			查询所有表名:select t.table_name from user_tables t;查询所有字段名:select t.column_name from user_col_comments t; ... 
- 洛谷P1072 [NOIP2009] Hankson 的趣味题
			P1072 Hankson 的趣味题 题目描述 Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson.现在,刚刚放学回家的 Hankson 正在思考一 ... 
- (转)Json在Unity中的简单使用
			Json数据解析在Unity3d中的应用 最近做项目过程中因为Json文件名写错了一个字母Unity报错,找错误找到半夜,当时为了验错,写了一个小Demo,正好借此总结一下Json. 1.什么是Jso ... 
- 微信网页授权demo1
			要授权首先要网页域名授权 然后就index.php代码如下 <?php require_once("./function.php"); $url = 'http://'.$_ ... 
- 五.反馈(Hopfield)神经网络
			前馈网络一般指前馈神经网络或前馈型神经网络.它是一种最简单的神经网络,各神经元分层排列.每个神经元只与前一层的神经元相连.接收前一层的输出,并输出给下一层,数据正想流动,输出仅由当前的输入和网络权值决 ... 
- Poj 1182种类(带权)并查集
			题目链接 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44316 Accepted: 12934 Descriptio ... 
- go strcut 封装
			package model import "fmt" type person struct { Name string age int //其它包不能直接访问.. sal floa ... 
- 为Array对象添加一个去除重复项的方法
			输入例子 [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN].uniq() 输出例子 [false, true, unde ... 
