2730: [HNOI2012]矿场搭建

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1602  Solved: 751
[Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

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

Sample Output

Case 1: 2 4
Case 2: 4 1

HINT

Case 1 的四组解分别是(2,4),(3,4),(4,5),(4,6);
Case 2 的一组解为(4,5,6,7)。

Source

day1

Solution

对于删除一个点,其余点要有出路,显然是和割点有关,那么我们求出所有割点,以及双连通分量。

对于一个双联通分量中,如果我们只删除一个割点或非割点,那么如果还有其余割点能使其余点到关键点,那么显然是不需要额外考虑的;如果没有其余的割点令我们到关键点,那么我们需要新建额外的关键点

分情况讨论,如果一个双联通分量里,有两个及以上割点,那么这个双联通分量里面是不需要额外建的

如果一个双联通分量里只有一个或没有割点,那么我们只需要再建一个即可。

至于方案数,可以利用乘法原理,我们把每个连通分量里的每个可以用来建成关键点的点用乘法统计起来即可

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define LL long long
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXM 1010
#define MAXN 80010
int N,M,tot;
LL sum;
struct EdgeNode{int next,to,from;}edge[MAXM<<];
int head[MAXN],cnt=;
void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
void InsertEdge(int u,int v) {AddEdge(u,v); AddEdge(v,u);}
#define Pa pair<int,int>
vector<int>BCC[MAXN];
Pa st[MAXM]; int top;
int dfn[MAXN],low[MAXN],dfsn,cut[MAXN],bcc,belong[MAXN];
void Tarjan(int now,int last)
{
dfn[now]=low[now]=++dfsn; int son=;
for (int i=head[now]; i; i=edge[i].next)
if (!dfn[edge[i].to])
{
st[++top]=make_pair(now,edge[i].to); son++;
Tarjan(edge[i].to,now); low[now]=min(low[now],low[edge[i].to]);
if (dfn[now]<=low[edge[i].to])
{
cut[now]=; bcc++; BCC[bcc].clear(); int tnow=-,tto=-;
while ()
{
tnow=st[top].first,tto=st[top].second; top--;
if (belong[tnow]!=bcc) BCC[bcc].push_back(tnow),belong[tnow]=bcc;
if (belong[tto]!=bcc) BCC[bcc].push_back(tto),belong[tto]=bcc;
if (tnow==now && tto==edge[i].to) break;
}
}
}
else if (dfn[edge[i].to]<dfn[now] && edge[i].to!=last)
st[++top]=make_pair(now,edge[i].to),low[now]=min(low[now],dfn[edge[i].to]);
if (last< && son==) cut[now]=;
}
int main()
{
int cas=;
while (scanf("%d",&M))
{
if (M==) break;
N=; cnt=; memset(head,,sizeof(head)); top=; bcc=; memset(st,,sizeof(st));
memset(dfn,,sizeof(dfn)); memset(low,,sizeof(low)); bcc=,dfsn=;
memset(cut,,sizeof(cut)); memset(belong,,sizeof(belong)); for (int x,y,i=; i<=M; i++) x=read(),y=read(),InsertEdge(x,y),N=max(N,max(x,y));
for (int i=; i<=N; i++) if (!dfn[i]) Tarjan(i,-);
// for (int i=1; i<=N; i++) printf("%d %d %d\n",dfn[i],belong[i],cut[i]);
tot=,sum=;
// printf("%d\n",bcc);
// for (int i=1; i<=bcc; i++) printf("%d ",BCC[i].size()); puts("");
for (int i=,num=,sz=BCC[i].size()-; i<=bcc; i++,num=,sz=BCC[i].size()-)
{
// printf("%d %d %I64d\n",num,tot,sum);
for (int j=; j<=sz; j++) if (cut[BCC[i][j]]) num++;
if (num==) tot++,sum*=(LL)(BCC[i].size()-num);
if (bcc==) {tot=; sum=(LL)BCC[].size()*(BCC[].size()-)/; break;}
}
printf("Case %d: %d %lld\n",++cas,tot,sum);
}
return ;
}

【BZOJ-2730】矿场搭建 Tarjan 双连通分量的更多相关文章

  1. BZOJ 2730 矿场搭建 Tarjan求割点

    思路: Tarjan求出来点双&割点 判一判就行了 //By SiriusRen #include <stack> #include <cstdio> #include ...

  2. bzoj2730矿场搭建——点双连通分量

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2730 首先一遍tarjan找出割点,将图缩点,这些大点中如果有只包含一个割点的,那么如果这个 ...

  3. BZOJ2730 [HNOI2012]矿场搭建[点双连通分量]

    看到删去一个点,需要剩下的都和关键点连通,有端联想到找点双,因为他怎么删点都是连通的. 对于一个孤立的点双,至少要设两个关键点. 如果两个点双以一个割点连接,假设断掉这个割点,两个块至少要各设一个关键 ...

  4. BZOJ 2730 矿场搭建

    割点 割点以外的点坍塌不影响其他人逃生,因为假设我们任取两个个非割点s建立救援站,非割点的任意点坍塌,我们都可以从割点走到一个救援出口. 所以我们只考虑割点坍塌的情况. 我们可以先找出图中所有的割点. ...

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

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

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

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

  7. [HNOI2012]矿场搭建 (点双连通)

    题目 [HNOI2012]矿场搭建 解析 这个题做的我十分自闭.. 没看出这个是个点双,然后一晚上+半上午.. 一看肯定和割点有关,我们找到所有的点双,会发现有这么几种情况 连通块中一个割点也没有,这 ...

  8. [BZOJ2730][HNOI2012]矿场搭建 点双 割点

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

  9. bzoj 1123 [POI2008]BLO——点双连通分量

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1123 点双连通分量缩点,然后各种各样. 结果不会写了.比如新连边.记录一个点是割点缩成的点还 ...

随机推荐

  1. Android源码分析之Handler

    接上一篇分析,正如Android doc所说,Handler主要有2方面用处: 1. delay执行同一线程中的某个操作,也就是schedule message.runnable在未来的某一时刻执行: ...

  2. iOS开发之XCode设置--消除AFN的警告

    本篇是直接拷贝别人的博文,地址:http://blog.csdn.net/liyiyismile/article/details/50434844 在项目开发中导入第三方sdk后会提示很多这样的错误: ...

  3. 当 IDENTITY_INSERT 设置为 OFF 时,不能向表 'OrderList' 中的标识列插入显式值

    问题描述:在SQL SERVER 2008中,向数据表中字段插入数据时,会报错,错误如下: 当 IDENTITY_INSERT 设置为 OFF 时,不能向表 'OrderList' 中的标识列插入显式 ...

  4. js,jq新增元素 ,on绑定事件无效

    在jquery1.7之后,建议使用on来绑定事件. $('.upload a').on('click',function(){ $(this).remove(); }) 在DOM渲染的时候,也就是ht ...

  5. ANDROID中去掉ACTIONBAR或TABWIDGET的分隔线

    在android中,有时需要对ActionBar或者TabWidget的分隔线进行定制,如取消,相关的属性设置为android:divider 以TabWidget为例,取消对应的函数: tabWid ...

  6. .replace(R.id.container, new User()).commit();/The method replace(int, Fragment) in the type FragmentTransaction is not app

    提示错误:The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arg ...

  7. 附加数据库后无法创建发布,error 2812 解决

    日前,由于业务需要,我要把一个数据库直接迁移到新的实例上 用的方法比较古老,就是直接停旧服务器,将数据文件复制到新服务器上,附加数据库 当然这个附加没有什么可说的了,但是在附加后需要将原来库上的发布重 ...

  8. 【WPF系列】基础学习-WPF架构概览

    引言 WPF从.net framewok3.0加入以来,经历了很多跟新.每次更新都给用户带来了新的功能或者优化性能.下面我们首先看下WPF再.netFramework中的位置,接着介绍下WPF的架构框 ...

  9. Android APP 读取 AndroidManifest.xml 中的版本信息详解

    APP都会涉及到版本的问题,Android APP的版本信息保存在AndroidManifest.xml文件的顶部.如下图: 有2个属性表示,“android:versionCode”和“androi ...

  10. 《InsideUE4》-6-GamePlay架构(五)Controller

    <InsideUE4>-6-GamePlay架构(五)Controller Tags: InsideUE4 GamePlay 那一天 Pawn又回想起了 被Controller所支配的恐惧 ...