[HNOI2012]矿场搭建

时间限制: 1 Sec  内存限制: 128 MB

题目描述

煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。

输入

输入文件有若干组数据,每组数据的第一行是一个正整数 N(N≤500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖       S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。

输出

输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。

样例输入

9
1 3
4 1
3 5
1 2
2 6
1 5
6 3
1 6
3 2
6
1 2
1 3
2 4
2 5
3 6
3 7
0

样例输出

Case 1: 2 4
Case 2: 4 1

提示

Case 1 的四组解分别是(2,4),(3,4),(4,5),(4,6);
  不知道有没有萌新和我一样,以为输出一个出去割点的联通块的个数和各个联通块的大小就完事了,事实证明,如果你A了超过1/3的点,算我输。
  事实上我们应当去对各个联通块进行分析,第一种,联通块在求的时候就没有碰到割点,那么它其实应该放两个安全出口,因为如果你放的那个刚好出了事故就没有别的安全出口了。第二种,只碰到了一个割点,那么就放一个出口就OK了。第三种,碰到了两个及两个以上的割点,那么我们就不用放了,无论那个割点出了事故我们都可以从别的地方走。
  至于方案数么,一个割点都没有的是size*(size-1)/2,注意特判size=1,有一个割点是size,有两个及两个以上割点无贡献。应该不用再分析了吧……

 #include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<string>
#include<cmath>
using namespace std;
struct ro{
int to,next;
}road[];
int zz,a[];
void build(int x,int y){
zz++;
road[zz].to=y;
road[zz].next=a[x];
a[x]=zz;
}
int v[],zz2,dfn[],low[];
void tar(int x,int root){
zz2++;
v[x]=;
dfn[x]=low[x]=zz2;
for(int i=a[x];i>;i=road[i].next)
{
int y=road[i].to;
if(!v[y])
{
tar(y,root);
low[x]=min(low[x],low[y]);
if(dfn[x]<=low[y])
{
v[x]++;
}
}
else
{
low[x]=min(low[x],dfn[y]);
}
}
if((x==root&&v[x]>)||(x!=root&&v[x]>))
{
v[x]=;
}
else
v[x]=; }
int m,top,st[],bj,jj,size,zzzz;
bool rz[],rz2[];
void work(int x){
zz2++;
dfn[x]=low[x]=zz2;
rz[x]=rz2[x]=;
top++;
st[top]=x;
for(int i=a[x];i>;i=road[i].next)
{
int y=road[i].to;
if(v[y]==)
{
if(!bj)
{
bj=y;
jj=;
}
else if(bj!=y) jj=;
continue;
}
if(!rz2[y])
{
work(y);
low[x]=min(low[x],low[y]);
}
else if(rz[y])
{
low[x]=min(low[x],dfn[y]);
}
}
if(dfn[x]==low[x])
{
int v;
zzzz++;
do{
v=st[top];
top--;
size++;
}while(dfn[v]!=low[v]);
}
}
int n;
int main(){
// freopen("bzoj_2730.in","r",stdin);
// freopen("bzoj_2730.out","w",stdout);
int js=;
while(~scanf("%d",&m))
{
if(m==) break;
js++;
zz=;
memset(a,,sizeof(a));
n=;
for(int i=;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
build(x,y);
build(y,x);
n=max(n,max(x,y));
}
memset(v,,sizeof(v));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
zz2=;
for(int i=;i<=n;i++)
{
if(!v[i])
{
zz2=;
tar(i,i);
}
}
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
zz2=;
memset(rz,,sizeof(rz));
memset(rz2,,sizeof(rz2));
long long an=,ans=;
top=;
memset(st,,sizeof(st));
for(int i=;i<=n;i++)
{
if(!rz2[i]&&v[i]!=)
{
jj=;
bj=;
size=;
work(i);
if(!jj)
{
an+=;
if(size!=) ans*=(size*(size-))/;
}
else if(jj==)
{
an++;
ans*=size;
}
}
}
printf("Case %d: %lld %lld\n",js,an,ans);
}
//while(1);
return ;
}
  

[HNOI2012]矿场搭建 题解的更多相关文章

  1. BZOJ2730:[HNOI2012]矿场搭建——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2730 https://www.luogu.org/problemnew/show/P3225 听说 ...

  2. P3225 [HNOI2012]矿场搭建 题解

    这道题挺难的,可以加深对割点的理解,还有,排列组合好重要了,分连通块,然后乘法原理(加法原理计数什么的) 传送门   https://www.luogu.org/problem/P3225 省选oi题 ...

  3. 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan

    [BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...

  4. [HNOI2012]矿场搭建(割点)

    [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出 ...

  5. bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1147  Solved: 528[Submit][Statu ...

  6. BZOJ 2730: [HNOI2012]矿场搭建( tarjan )

    先tarjan求出割点.. 割点把图分成了几个双连通分量..只需dfs找出即可. 然后一个bcc有>2个割点, 那么这个bcc就不用建了, 因为一定可以走到其他救援出口. 只有一个割点的bcc就 ...

  7. 洛谷 P3225 [HNOI2012]矿场搭建 解题报告

    P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...

  8. 【BZOJ】2730: [HNOI2012]矿场搭建【Tarjan找割点】【分联通块割点个数】

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3230  Solved: 1540[Submit][Stat ...

  9. Tarjan 点双+割点+DFS【洛谷P3225】 [HNOI2012]矿场搭建

    P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...

随机推荐

  1. CentOS7下Docker安装

    Docker现在有CE和EE版本 , CE版本是免费版本 , 该文档安装的就是CE版本 1.删除旧版本docker 保险起见 , 走流程 yum remove docker \ docker-clie ...

  2. Win8 Metro(C#)数字图像处理--2.64图像高斯滤波算法

    原文:Win8 Metro(C#)数字图像处理--2.64图像高斯滤波算法  [函数名称]   高斯平滑滤波器      GaussFilter(WriteableBitmap src,int r ...

  3. 天气预报API接口

    原文:天气预报API接口 一.中央气象台API接口: 1. XML接口 http://flash.weather.com.cn/wmaps/xml/china.xml 这个是全国天气的根节点,列出所有 ...

  4. 如何线程调用C++类成员函数

    方法就是: 1,写成静态成员函数 2,参数为 (void* __this)用来传入类 对象指针(this) 3,进入函数首先    C类名 *_this = (C类名*)__this;  转化为对象指 ...

  5. C#应用配置信息保存和读取

    //保存信息 SystemConfig.WriteConfigData(“字段名称”, “这里是需要保存的内容”); //读取信息 SystemConfig.GetConfigData(“字段名称”, ...

  6. NBU客户端安装失败

    该服务器是阿里云上的centos6.8,是用来做oracle服务器,买来之后进行测试,发现没有安装图形化界面,还有部分包也没有安装.在oracle安装完成之后,尝试安装NBU的客户端,结果发生报错:T ...

  7. CDC-更改数据捕获存储过程 (Transact-SQL)-学习

    背景: 在SQLServer2008之前,对数据变更的捕获通常使用触发器.时间戳等低效高成本的功能来实现,所以很多系统都没有做数据变更或者仅仅对核心表做监控. 适用环境: 仅在SQLServer200 ...

  8. file.delete()与file.deleteOnExit(); 的区别

    file.delete()   //删除文件,删除的是创建File对象时指定与之关联创建的那个文件.这是一个立刻执行的操作 file.deleteOnExit();   //在JVM进程退出的时候删除 ...

  9. c# 查询本机可用的代理ip

    现在有很多网站都提供免费的代理ip,但是你会发现很多网站显示的可以用的 ,在自己电脑上是用不了,写个小代码提取出自己电脑上可以用的代理,没什么技术含量,只是为了记录一下 string strUrl = ...

  10. Windows下配置QT OpenCV

    OpenCV-Study:Windows下配置OpenCV 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:XP OpenCV版本:2.4 ...