P3225 [HNOI2012]矿场搭建

题目描述

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

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

点双入门。。。 话说题意是真的晦涩。

一眼求割点,求完割点怎么办?

因为我们把割点去掉之后,图中会剩下一个一个的块,这些块就是点双。

那么限制工人逃跑的就是割点,所以我们在乎的是每个点双中有多少个割点。

那么我们就可以通过Tarjan给所有割点打上一个标记。

然后再去DFS出所有的点双,这个过程需要记录点双中的点和点双中的割点数。有些细节。

然后就可以愉快地分情况讨论了。

(一),当前点双内没有割点,那么这个点双是独立的也就是不和其他的块联通,那么对于这个点双内的点我们就需要建立两个救援出口,为什么呢,因为有一个炸了还有另外一个。所以\(ans1+=2\)

然后方案数通过乘法原理和组合数搞一搞就行了,也就是\(ans2*=C(tot,2)\)。

(二),当前点双内只有一个割点,那么可以知道如果这个割点炸了我们就翻车了,所以我们可以继承(一)的思想,只是把这个已有的割点看成一个必然的出口,所以我们还需要建1个出口,方案数为\(ans2*=C(tot,1)\)。

(三),当前点双内有两个割点,还是一样的思想,就会发现我们不用再建出口了,因为可以把两个割点看成两个出口,任意一个炸了我们还有另一个。

ok,那就可以开始愉快地写代码了喵喵喵。。。

code:

#include <iostream>
#include <cstdio>
#include <cstring> using namespace std; #define int long long const int wx=517; inline int read(){
int sum=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();}
return sum*f;
} int n,m,ans1,ans2,num,sjc,tot,zmj,cnt;
int dfn[wx],head[wx],ok[wx],vis[wx],low[wx]; struct e{
int nxt,to;
}edge[wx*2]; void add(int from,int to){
edge[++num].nxt=head[from];
edge[num].to=to;
head[from]=num;
} void Tarjan(int u,int f){
dfn[u]=low[u]=++tot; int child=0;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==f)continue;
if(!dfn[v]){
Tarjan(v,u);
child++;
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])ok[u]=1;
}
else if(dfn[v]<dfn[u]&&v!=f){
low[u]=min(low[u],dfn[v]);
}
}
if(child<=1&&f==-1)ok[u]=0;
} void dfs(int u){
vis[u]=tot; zmj++;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(vis[v]!=vis[u]&&ok[v])cnt++,vis[v]=tot;
if(!vis[v]&&!ok[v])dfs(v);
}
} void clear(){
num=0,tot=0;
memset(head,0,sizeof head);
memset(edge,0,sizeof edge);
memset(vis,0,sizeof vis);
memset(dfn,0,sizeof dfn);
memset(ok,0,sizeof ok);
} signed main(){
while(1){
m=read(); if(!m)break;
n=0; sjc++; ans1=0; ans2=1;
clear();
for(int i=1;i<=m;i++){
int x,y;
x=read(); y=read();
add(x,y); add(y,x); n=max(n,max(x,y));
}
for(int i=1;i<=n;i++)if(!dfn[i])Tarjan(i,-1);
for(int i=1;i<=n;i++){
if(ok[i]||vis[i])continue;
tot++; zmj=0,cnt=0; dfs(i);
if(cnt==0)ans1+=2,ans2*=(zmj-1)*zmj/2;
if(cnt==1)ans1++,ans2*=zmj;
}
printf("Case %lld: %lld %lld\n",sjc,ans1,ans2);
}
return 0;
}

Tarjan 点双+割点+DFS【洛谷P3225】 [HNOI2012]矿场搭建的更多相关文章

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

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

  2. 洛谷——P3225 [HNOI2012]矿场搭建

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

  3. 洛谷P3225 HNOI2012 矿场搭建

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

  4. 洛谷—— P3225 [HNOI2012]矿场搭建

    https://www.luogu.org/problem/show?pid=3225 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有 ...

  5. 洛谷 P3225 [HNOI2012]矿场搭建

    传送门 题目大意:建设几个出口,使得图上无论哪个点被破坏,都可以与出口联通. 题解:tarjian求割点 首先出口不能建在割点上,找出割点,图就被分成了几个联通块. 每个联通块,建出口.如果割点数为0 ...

  6. BZOJ2730或洛谷3225 [HNOI2012]矿场搭建

    BZOJ原题链接 洛谷原题链接 显然在一个点双连通分量里,无论是哪一个挖煤点倒塌,其余挖煤点就可以互相到达,而对于一个点双连通分量来说,与外界的联系全看割点,所以我们先用\(tarjan\)求出点双连 ...

  7. [Luogu] P3225 [HNOI2012]矿场搭建

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

  8. P3225 [HNOI2012]矿场搭建

    传送门 对于一个点双联通分量,如果它连接了两个或更多割点 那么不论哪个点GG都有至少一条路通到其他的点双联通分量,所以我们不用考虑 如果它只连接一个割点,如果这个割点GG,那整个块也一起GG,所以要再 ...

  9. P3225 [HNOI2012]矿场搭建 割点 tarjan 双联通分量

    https://www.luogu.org/problemnew/show/P3225 题意 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条 ...

随机推荐

  1. cacti启动有图无数据

    cactiEZ服务器重启后,获取不到图形的解决办法 cd /var/www/html/cli/ php -q rebuild_poller_cache.php -d myisamchk --safe- ...

  2. CSS秘密花园:多边框

    今天在查询CSS3动画相关资料时偶然发现这个,感觉有时还是挺方便的.原文链接:http://www.w3cplus.com/css3/css-secrets/multiple-borders.html ...

  3. c++多线程编程(三)

    关于WaitForSingleObject函数用法 : 用户模式的线程同步机制效率高,如果需要考虑线程同步问题,应该首先考虑用户模式的线程同步方法. 但是,用户模式的线程同步有限制,对于多个进程之间的 ...

  4. 【bzoj1056】排名系统

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2195  Solved: 623[Submit][Statu ...

  5. 基于Nginx实现集群原理

    1)安装Nginx 2)配置多个Tomcat,并修改端口号(两个端口号不一样即可) 3)在Nginx的Nginx.conf添加如下配置:

  6. jQuery--加一行减一行

    效果: 知识点: 克隆--clone() 追加--append() 移除--remove() 代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2 ...

  7. cakephp重写配置

    开启重新: (1)开启服务器的mod_rewrite模块 (2)注释掉app/ConfigScore.php中的 Configure::write('App.baseUrl', env('SCRIPT ...

  8. [Lua快速了解一下]Lua的控制语句

    -Lua中没有++或者--的骚操作 -while loop sum = num = do sum = sum + num num = num + end print("sum =" ...

  9. LIS问题---HDU1025 Constructing Roads In JGShining's Kingdom

    发现这个说的比较通俗: 假设存在一个序列d[1..9] = 2 1 5 3 6 4 8 9 7,可以看出来它的LIS长度为5.下面一步一步试着找出它.我们定义一个序列B,然后令 i = 1 to 9 ...

  10. 国外物联网平台(7):FogHorn

    国外物联网平台(7) ——FogHorn 马智 引言: 据外媒在本月20日报道,硅谷初创公司FogHorn正在与谷歌合作以简化工业物联网应用的部署.本文对FogHorn的技术.产品.应用和生态进行了分 ...