洛谷 P3225 [HNOI2012]矿场搭建 解题报告
P3225 [HNOI2012]矿场搭建
题目描述
煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条道路通向救援出口。
请写一个程序,用来计算至少需要设置几个救援出口,以及不同最少救援出口的设置方案总数。
输入输出格式
输入格式:
输入文件有若干组数据,每组数据的第一行是一个正整数 N(N<=500),表示工地的隧道数,接下来的 N 行每行是用空格隔开的两个整数 S 和 T,表示挖 S 与挖煤点 T 由隧道直接连接。输入数据以 0 结尾。
输出格式:
输入文件中有多少组数据,输出文件 output.txt 中就有多少行。每行对应一组输入数据的 结果。其中第 i 行以 Case i: 开始(注意大小写,Case 与 i 之间有空格,i 与:之间无空格,: 之后有空格),其后是用空格隔开的两个正整数,第一个正整数表示对于第 i 组输入数据至少需 要设置几个救援出口,第二个正整数表示对于第 i 组输入数据不同最少救援出口的设置方案总 数。输入数据保证答案小于 2^64。输出格式参照以下输入输出样例。
最开始想的是统计把所有割点割掉之后联通分量的块数,就没怎么想了10分,谁知道这题是个分类讨论。
我们讨论最初的每个联通分量。
- 当这个联通分量是个双联通分量,即没有割点的联通分量时。
若这个联通分量大小是1,则一定出口++,方案不变。
若这个联通分量大小大于1,则出口设2个(防止某个出口被爆),方案乘上\(C_n^2\),\(n\)为联通块大小。 - 当这个联通分量存在割点时。
我们讨论分离出割点后它的每一个双联通分量。
若它的一个双联通分量(整体)与一个割点相连,则出口++,方案乘上双联通分量大小。
原因:当双联通分量中的点爆掉后,从割点跑(到另外的双联通分量);当割点爆掉后,从双联通分量中设的点跑。
若它的一个双联通分量与至少两个割点相连,这个双联通分量不用设出口,因为不管是割点爆还是里面爆,都可以向另外的双联通分量跑。
对于为什么跑向别的双联通分量后一定有出口,可以这么想,对于每一个 有很多个割点与双联通分量相连构成的 联通分量,至少存在两端是 与一个割点连接的双联通分量,这样的双联通分量是一定要设出口的。
code:
#include <cstdio>
#include <cstring>
#define ll long long
int min(int x,int y){return x<y?x:y;}
const int N=504;
struct Edge
{
int to,next;
}edge[N<<1];
int head[N],cnt=0;
void add(int u,int v)
{
edge[++cnt].next=head[u];edge[cnt].to=v;head[u]=cnt;
}
int dfn[N<<1],low[N<<1],vis[N<<1],used[N<<1],is[N<<1];
int m,n,k=0,time=0;
ll ans1,ans2,siz,cut;
void tarjan(int now,int fa)
{
int child=0;
dfn[now]=low[now]=++time;
for(int i=head[now];i;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v,fa);
low[now]=min(low[now],low[v]);
if(low[v]>=dfn[now]&&now!=fa)
vis[now]=1;
if(now==fa) child++;
}
low[now]=min(low[now],dfn[v]);
}
if(fa==now&&child>1)
vis[now]=1;
}
void dfs(int now)
{
used[now]=1;
siz++;
for(int i=head[now];i;i=edge[i].next)
{
int v=edge[i].to;
if(!vis[v]&&!used[v]) dfs(v);
if(vis[v]&&!is[v]) cut++,is[v]=1;
}
}
void init()//记得待会检查全不全
{
memset(head,0,sizeof(head));
memset(used,0,sizeof(used));
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
cnt=0,n=0,time=0,ans1=0,ans2=1,cnt=0,k++;
}
int main()
{
scanf("%d",&m);
while(m)
{
init();
int u,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
if(!used[u])
{
used[u]=1;
n++;
}
if(!used[v])
{
used[v]=1;
n++;
}
}
for(int i=1;i<=n;i++)
if(!dfn[i]&&!vis[i])
tarjan(i,i);
memset(used,0,sizeof(used));
for(int i=1;i<=n;i++)
if(!vis[i]&&!used[i])
{
siz=0;
cut=0;
memset(is,0,sizeof(is));
dfs(i);
if(!cut)
{
if(siz!=1)
{
ans1+=2;
ans2*=siz*(siz-1)/2;
}
else
ans1++;
}
else if(cut==1)
{
ans1++;
ans2*=siz;
}
}
printf("Case %d: %lld %lld\n",k,ans1,ans2);
scanf("%d",&m);
}
}
2018.6.8
洛谷 P3225 [HNOI2012]矿场搭建 解题报告的更多相关文章
- 洛谷——P3225 [HNOI2012]矿场搭建
P3225 [HNOI2012]矿场搭建 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤 ...
- 洛谷P3225 HNOI2012 矿场搭建
题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之 ...
- 洛谷 P3225 [HNOI2012]矿场搭建
传送门 题目大意:建设几个出口,使得图上无论哪个点被破坏,都可以与出口联通. 题解:tarjian求割点 首先出口不能建在割点上,找出割点,图就被分成了几个联通块. 每个联通块,建出口.如果割点数为0 ...
- 洛谷—— P3225 [HNOI2012]矿场搭建
https://www.luogu.org/problem/show?pid=3225 题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有 ...
- BZOJ2730或洛谷3225 [HNOI2012]矿场搭建
BZOJ原题链接 洛谷原题链接 显然在一个点双连通分量里,无论是哪一个挖煤点倒塌,其余挖煤点就可以互相到达,而对于一个点双连通分量来说,与外界的联系全看割点,所以我们先用\(tarjan\)求出点双连 ...
- 洛谷_Cx的故事_解题报告_第四题70
1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h> struct node { long x,y,c; ...
- 洛谷 P2317 [HNOI2005]星际贸易 解题报告
P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...
- 洛谷 P3802 小魔女帕琪 解题报告
P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...
- 洛谷 P2606 [ZJOI2010]排列计数 解题报告
P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...
随机推荐
- SpringBoot日记——任务处理 之 异步、定时、邮件
---恢复内容开始--- 直接步入正题. 异步任务 异步任务比较简单,只需要两个注解就可以搞定,我们直接来看如何使用: 1.创建一个service,带上@EnableAsync,就是开启异步任务的注解 ...
- .NETCore_生成实体
先安装以下三个包,或者使用Nuget引用 不要问我为什么,按哥说的做吧: Install-Package Microsoft.EntityFrameworkCore.SqlServer Install ...
- html绝对路径,相对路径
.com/eat.php中引用.com/includes/headrt.php的话写includes/header.php .com/service/eat.php中引用.com/includes/h ...
- libmysqlclient.so.16: cannot open shared object file: No such file or directory
编译安装的mysql5.6.39,安装目录是/usr/local/mysql,启用程序时报错:libmysqlclient.so.16: cannot open shared object file: ...
- 先埋锅-CF-Valid BFS?-差一点没交上
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> ...
- 剑值offer:最小的k个数
这是在面试常遇到的topk问题. 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 解题思路: 思路一:用快排对数 ...
- Oracle系列(三): 情景查询一 a表中有个fid字段,逗号分隔开来,b表中有id字段及其他信息,如何关联a表的fid和和b表的id字段查询
现在有两个表,表a中 DOC FID 1 a,b,c 2 a,c,d 表b中 ID KEY a A b B c C d D 怎么联合查询出 DOC FID KEY 1 a,b,c A,B,C 2 a, ...
- Oracle系列(二): Oracle表的外键查询
在执行数据库删除操作时,外键关联是令我们最烦的一个东西,有了外键关联,就不允许随意删除数据,那么怎知道这个外键关联度的外键属于那个表? select * from user_cons_columns ...
- shell脚本--逻辑判断与字符串比较
涉及到比较和判断的时候,要注意 整数比较使用-lt,-gt,ge等比较运算符,详情参考:整数比较 文件测试使用 -d, -f, -x等运算发,详情参考:文件测试 逻辑判断使用 && ...
- 安裝CentOS7后修復win7引导
想尝试双系统的心情想必大家都能理解,但是安装了双系统之后的收尾工作也是必不可少的,由于对Linux并不算很熟悉,所以在这方面花了不少时间,这里将CentOS7下修復windows7引导的解决方案记录下 ...