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个及以上割顶的双连通分量可以不 ...
随机推荐
- CentOS 7安装与配置Tomcat8
1.下载安装包并上传服务器 2.解压 tar -zxvf apache-tomcat-8.5.16.tar.gz -C /opt/java 3.启动 cd /opt/java/apache-tomca ...
- 操作系统Lab1 详解(boot|kern/debug)
总体 : boot kern libs tools boot asm.h bootmain.c bootasm.S asm.h 汇编头文件 SEG_NULLASM 定义一个空段描述符 SEG_ASM ...
- POJ1991 NOI1999棋盘分割
棋盘分割 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 15581 Accepted: 5534 Description ...
- php收集表单数据-$GET和$POST的区别
学习笔记: $_GET 变量 预定义的 $_GET 变量用于收集来自 method="get" 的表单中的值. 从带有 GET 方法的表单发送的信息(例如:http://www.r ...
- Serializable 可串行化接口
Serializable 可串行化接口 定义一个User类,实现Serializable接口: package com.monkey1025; import java.io.Serializable; ...
- python正则表达式应用 定义一个函数,求字符串中出现的所有整数之和
- 【水滴石穿】rn_statusbar
先放项目地址https://github.com/hezhii/rn_statusbar 来看一下效果 咩有感觉很怎么样,看代码 根入口文件 //index.js //看代码我们知道入口是app.js ...
- Sublime中输入中文的解决方案
之前系统用的输入法是 ibus,在sublime中无法使用, 可能是不支持该输入法. 然后改用 fcitx,切换输入法之后要重启系统才可以生效, 启动之后就可以使用中文了.
- R语言数据分析利器data.table包—数据框结构处理精讲
R语言数据分析利器data.table包-数据框结构处理精讲 R语言data.table包是自带包data.frame的升级版,用于数据框格式数据的处理,最大的特点快.包括两个方面,一方面是写的快,代 ...
- SWF在线绘本批量制作高质量PDF的新方法(重点在批量制作)
SWF在线绘本批量制作高质量PDF的新方法(重点在批量制作) 2012-12-21 未来决定... http://www.ebama.net/thread-107643-1-1.html ...