题目

Description

煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。

请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。

Input

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

Output

输入文件中有多少组数据,输出文件中就有多少行。每行对应一组输入数据的结果。

其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与 : 之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i组输入数据至少需要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总数。

输出格式参照以下输入输出样例。

题解

再点双连通分量中,如果坏了其中一个点,那么剩下的点还是连通的,所以我们求一次点双连通分量,再仔细观察一下,如果一个点双中(非割点点数为 \(n\)):

  1. 没有割点,那么显然要两个通道,共 \(C_n^2\) 种选法。
  2. 有一个割点,那么在这个点双中就要有一个通道,共,有一个割点,那么在这个点双中就要有一个通道,共 \(n\) 种选法。
  3. 有两个或者两个以上的割点,则不需要通道。

问题解决了,不过我可能是太弱了,统计割点数和非割点数写挂了,我们其实可以把每个割点找出来,dfs 一遍,割点之间就是一个点双,另外相邻的割点也属于这个点双。

CODE

#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
using namespace std; int dfn[10005],low[10005],cp[10005],cnt=0;
int bcc[10005],num[10005],son[10005],C=0;
bool vis[100005],iscp[100005];
int n,m,x,y,h[100005],tot=0,cas=0;
struct Edge{
int x,next;
}e[200005]; inline void add_edge(int x,int y){
e[++tot].x=y;
e[tot].next=h[x],h[x]=tot;
} stack<int> s; void tarjan(int x,int fa){
low[x]=dfn[x]=++cnt;
son[x]=0;
for(int i=h[x];i;i=e[i].next){
if(e[i].x==fa)continue;
if(!dfn[e[i].x]){
tarjan(e[i].x,x),son[x]++;
low[x]=min(low[x],low[e[i].x]);
if(low[e[i].x]>=dfn[x]&&fa!=0)iscp[x]=true;
}
else low[x]=min(low[x],dfn[e[i].x]);
}
if(son[x]>1&&fa==0)iscp[x]=true;
} void dfs(int x){
vis[x]=true,num[C]++;
for(int i=h[x];i;i=e[i].next){
if(vis[e[i].x])continue;
if(!iscp[e[i].x])dfs(e[i].x);
else{
if(bcc[e[i].x]!=C)
bcc[e[i].x]=C,cp[C]++;
}
}
} int main(){
while(scanf("%d",&m),m){
memset(h,0,sizeof(h));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(bcc,0,sizeof(bcc));
memset(num,0,sizeof(num));
memset(cp,0,sizeof(cp));
memset(iscp,0,sizeof(iscp));
memset(vis,0,sizeof(vis));
tot=cnt=C=n=0;
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
n=max(n,max(x,y));
}
for(int i=1;i<=n;i++)
if(!dfn[i])tarjan(i,0);
unsigned long long sum=0,ans=1;
for(int i=1;i<=n;i++){
if(!iscp[i]&&!vis[i]){
C++,dfs(i);
if(cp[C]==1)sum++,ans*=num[C];
}
}
if(C==1)sum=2,ans=n*(n-1)/2;
printf("Case %d: ",++cas);
printf("%llu %llu\n",sum,ans);
}
}

[HNOI2012]矿场搭建(tarjan求点双)的更多相关文章

  1. bzoj 2730: [HNOI2012]矿场搭建——tarjan求点双

    Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一 ...

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

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

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

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

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

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

  5. BZOJ2730 [HNOI2012]矿场搭建 - Tarjan割点

    Solution 输入中没有出现过的矿场点是不用考虑的, 所以不用考虑只有 一个点 的点双联通分量. 要使某个挖矿点倒塌, 相当于割去这个点, 所以我们求一遍割点和点双联通分量. 之后的点双联通分量构 ...

  6. P3225 [HNOI2012]矿场搭建 tarjan割点

    这个题需要发现一点规律,就是先按割点求块,然后求每个联通块中有几个割点,假如没有割点,则需要建两个出口,如果一个割点,则需要建一个出口,2个以上不用建. 题干: 题目描述 煤矿工地可以看成是由隧道连接 ...

  7. [BZOJ2730][HNOI2012]矿场搭建(求割点)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2730 分析: 如果坍塌的点不是割点,那没什么影响,主要考虑坍塌的点是割点的情况. 显然 ...

  8. C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建

    最近在学图论相关的内容,阅读这篇博客的前提是你已经基本了解了Tarjan求点双. 由割点的定义(删去这个点就可使这个图不连通)我们可以知道,坍塌的挖煤点只有在割点上才会使这个图不连通,而除了割点的其他 ...

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

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

  10. 【BZOJ-2730】矿场搭建 Tarjan 双连通分量

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

随机推荐

  1. .NET下寄宿于控制台的HTTPS监听

    附上原文链接:https://blogs.msdn.microsoft.com/jpsanders/2009/09/29/how-to-walkthrough-using-httplistener-o ...

  2. 用dom1来实现,根据光标移动自动给表单加上背景色,光标移开自动去除背景色

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. session 关于localhost和本地IP地址 不共享问题

    打比方,  一个请求 localhost:8080/test/test  ,一个本地Ip(172.1.1.1:8080/test/test) 1.请求localhost方式 HttpSession s ...

  4. DevOps - 版本控制 - Gogs

    Gogs Gogs官网:https://gogs.io Gogs文档:https://gogs.io/docs Gogs配置文件手册:https://gogs.io/docs/advanced/con ...

  5. Mysql存储过程中的事务回滚

    create procedure test(in a int) BEGIN ; ;-- 异常时设置为1 START TRANSACTION; ,); ,); THEN ROLLBACK; ELSE C ...

  6. Python 频繁请求问题: [Errno 104] Connection reset by peer

    Table of Contents 1. 记遇到的一个问题:[Errno 104] Connection reset by peer 记遇到的一个问题:[Errno 104] Connection r ...

  7. 17,基于scrapy-redis两种形式的分布式爬虫

    redis分布式部署 1.scrapy框架是否可以自己实现分布式? - 不可以.原因有二. 其一:因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls ...

  8. 10,Scrapy简单入门及实例讲解

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以 ...

  9. P3376 【模板】网络最大流dinic算法

    P3376 [模板]网络最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点 ...

  10. springcloud 高可用分布式配置中心

    SpringCloud教程七:高可用的分布式配置中心(SpringCloud Config) 当服务有很多 都要从服务中心获取配置时 这是可以将服务中心分布式处理 是系统具备在集群下的大数据处理 主要 ...