洛谷 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\) ...
随机推荐
- Luogu P1337 [JSOI2004]平衡点 / 吊打XXX
一道入门模拟退火的经典题,还是很考验RP的 首先我们发现神TM这道题又和物理扯上了关系,其实是一道求广义费马点的题目 首先我们可以根据物理知识得到,当系统处于平衡状态时,系统的总能量最小 又此时系统的 ...
- 详解javascript中this的工作原理
在 JavaScript 中 this 常常指向方法调用的对象,但有些时候并不是这样的,本文将详细解读在不同的情况下 this 的指向. 一.指向 window: 在全局中使用 this,它将会指向全 ...
- Mvc4_ @RenderBody、@RenderPage、@RenderSection用法
一.@RenderBody 当创建基于_Layout.cshtml布局页面的视图时,视图的内容会和布局页面合并,而新创建视图的内容会通过_Layout.cshtml布局页面的@RenderBody() ...
- 移动端触摸(touch)事件
移动端时代已经到来,作为前端开发的我们没有理由也不应该坐井观天,而是勇敢地跳出心里的那口井,去拥抱蔚蓝的天空.该来的总会来,我们要做的就是接受未知的挑战.正如你所看到的,这是一篇关于移动端触摸事件的文 ...
- Hybrid APP基础篇(一)->什么是Hybrid App
最新更新 一个开源的快速混合开发框架:https://github.com/quickhybrid/quickhybrid Android.iOS.JS三端内容初步都已经完成,有完善的设计思路.教程以 ...
- Github的建立及心得体会
第一次接触Github,这次注册最大的难处就是全英文,着实看不懂.仅凭着认识的几个常用词去了解个具体内容实在是太困难了.所以第一个体会就是要好好学英语背单词,不想看到满屏的英文就感觉头疼,烦躁.第二个 ...
- java感想
Java学起来很有趣,通过学习Java可以提高自己的逻辑能力.在学习Java期间我们做了一些程序,我们班的同学也都积极准备,完成的还不错!在做程序时,我遇到了一些难题,有时也会出现错误,时间长了弄得我 ...
- Java web错误总结~
1.java程序中没有错,但是项目上面显示一个红叉的解决办法 错误信息: 报Description Resource Path Location Type Java compiler level d ...
- SQL中常用函数
SELECT CONVERT(varchar(100), GETDATE(), 23) AS 日期 结果:2017-01-05 select ISNULL(price,'0.0') ...
- Spring注解 开发