洛谷——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。输出格式参照以下输入输出样例。
输入输出样例
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
Case 1: 2 4 Case 2: 4 1
说明
Case 1 的四组解分别是(2,4),(3,4),(4,5),(4,6);
Case 2 的一组解为(4,5,6,7)。
分情况讨论:
很显然是要求割点嘛、、、(分类上写着、、、)
好吧,求完割点以后干什么??
我一直认为是先求出割点,然后将割点全部炸掉(屏蔽)后求出每个联通块的点的个数,然后在用乘法原理来做。
结果发现全wa!!!(ORZ)
据说这道题要分类讨论、、、、
①若一个双联通中没有割点,那么最少需要两个出口(炸了一个去另一个)
②若一个双联通能连到一个割点,那么最少需要在双联通中设置一个出口,炸了割点还能逃生、
③若一个双联通能连到多余一个割点,那么不管怎么炸,都能从没炸的割点跑到别的分量里
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 510
using namespace std;
long long ans2;
bool vis[N],cut_point[N];
int n,m,x,y,s,tot,tim,cnt,cut,sum,ans1;
int dfn[N],low[N],head[N],belong[N];
int read()
{
,f=; char ch=getchar();
; ch=getchar();}
+ch-'; ch=getchar();}
return x*f;
}
struct Edge
{
int from,to,next;
}edge[N<<];
int add(int x,int y)
{
tot++;
edge[tot].to=y;
edge[tot].next=head[x];
head[x]=tot;
}
int begin()
{
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(edge,,sizeof(edge));
memset(head,,sizeof(head));
memset(belong,,sizeof(belong));
memset(cut_point,,sizeof(cut_point));
n=,tot=,ans1=,ans2=,tim=,sum=;
}
int tarjan(int now,int pre)
{
dfn[now]=low[now]=++tim;
; bool boo=false;
for(int i=head[now];i;i=edge[i].next)
{
int t=edge[i].to;
^i)==pre) continue;
if(!dfn[t])
{
tt++;tarjan(t,i);
low[now]=min(low[now],low[t]);
if(dfn[now]<=low[t]) boo=true;
}
else low[now]=min(low[now],dfn[t]);
}
) {) cut_point[now]=true;}
else if(boo) cut_point[now]=true;
}
int dfs(int x)
{
s++;
vis[x]=true;
belong[x]=sum;
for(int i=head[x];i;i=edge[i].next)
{
int t=edge[i].to;
if(cut_point[t]&&belong[t]!=sum) cut++,belong[t]=sum;
if(!vis[t]&&!cut_point[t]) dfs(t);
}
}
int main()
{
)
{
m=read();) break;
begin();
;i<=m;i++)
{
x=read(),y=read();
add(x,y),add(y,x);
n=max(max(x,y),n);
}
;i<=n;i++)
);
;i<=n;i++)
{
if(vis[i]||cut_point[i]) continue;
s=,cut=;
sum++;dfs(i);
,ans2*=()>>);
) ans1++,ans2*=(long long)s;
}
printf("Case %d: %d %lld\n",++cnt,ans1,ans2);
}
;
}
傻不拉几的只考虑一种情况还调试半天、、、、结果全wa
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 11000
using namespace std;
bool vis[N],cut_point[N];
int n,m,tot,tim,sum,cnt,top,ans1,ans2;
int x[N],y[N],dfn[N],low[N],ans[N],head[N],stack[N],belong[N];
int read()
{
,f=; char ch=getchar();
; ch=getchar();}
+ch-'; ch=getchar();}
return x*f;
}
struct Edge
{
int from,to,next;
}edge[N];
int add(int x,int y)
{
tot++;
edge[tot].to=y;
edge[tot].next=head[x];
head[x]=tot;
}
int tarjan(int x,int pre)
{
; bool boo;
dfn[x]=low[x]=++tim;
vis[x]=true;
for(int i=head[x];i;i=edge[i].next)
{
int t=edge[i].to;
^i)==pre) continue;
if(!vis[t])
{
s++;tarjan(t,i);
low[x]=min(low[t],low[x]);
if(low[t]>=dfn[x]) boo=true;
}
else low[x]=min(low[x],dfn[t]);
}
) cut_point[x]=true;}
else {if(boo) cut_point[x]=true;}
}
int tarjan1(int now)
{
dfn[now]=low[now]=++tim;
stack[++top]=now;vis[now]=true;
for(int i=head[now];i;i=edge[i].next)
{
int t=edge[i].to;
if(vis[t]) low[now]=min(low[now],dfn[t]);
else if(!dfn[t]) tarjan1(t),low[now]=min(low[now],low[t]);
}
if(dfn[now]==low[now])
{
sum++; belong[now]=sum;ans[sum]++;
for(;stack[top]!=now;top--)
belong[stack[top]]=sum,vis[stack[top]]=false,ans[sum]++;
vis[now]=false; top--;
}
}
int begin()
{
tot=,tim=,sum=,ans2=;
memset(ans,,sizeof(ans));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
memset(head,,sizeof(head));
memset(belong,,sizeof(belong));
}
int main()
{
)
{
m=read();) break;
begin();cnt++,tot=;
memset(cut_point,,sizeof(cut_point));
;i<=m;i++)
x[i]=read(),y[i]=read(),add(x[i],y[i]),add(y[i],x[i]);
tarjan(,); begin();
;i<=m;i++)
{
n=max(max(x[i],y[i]),n);
if(cut_point[x[i]]||cut_point[y[i]]) continue;
add(x[i],y[i]),add(y[i],x[i]);
}
;i<=n;i++)
if(!dfn[i]&&!cut_point[i]) tarjan1(i);
ans1=sum;
;i<=sum;i++)
ans2*=ans[i];
printf("Case %d: %d %d\n",cnt,ans1,ans2);
}
;
}
洛谷——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\)求出点双连 ...
- P3225 [HNOI2012]矿场搭建 割点 tarjan 双联通分量
https://www.luogu.org/problemnew/show/P3225 题意 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条 ...
- P3225 [HNOI2012]矿场搭建 题解
这道题挺难的,可以加深对割点的理解,还有,排列组合好重要了,分连通块,然后乘法原理(加法原理计数什么的) 传送门 https://www.luogu.org/problem/P3225 省选oi题 ...
- P3225 [HNOI2012]矿场搭建
传送门 对于一个点双联通分量,如果它连接了两个或更多割点 那么不论哪个点GG都有至少一条路通到其他的点双联通分量,所以我们不用考虑 如果它只连接一个割点,如果这个割点GG,那整个块也一起GG,所以要再 ...
- [Luogu] P3225 [HNOI2012]矿场搭建
题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之 ...
随机推荐
- 打开centos直接进入文本模式命令行
2.打开/etc/inittab 文件 #vim /etc/inittab3.在默认的 run level 设置中,可以看到第一行书写如:id:5:initdefault:(默认的 run level ...
- virtualbox没有64位选项
今天安装的virtualbox想安装一下sql server 测试一下 在安装系统的时候发现没有64位系统的选项,在网上找了一下 发现是 在BIOS里面有一个选项没有开启, 是 Intel virt ...
- Two-Phase Commit (2PC)
两阶段提交模式像极了比赛发令:“预备,开始!”
- 2015 AlBaath Collegiate Programming Contest(2月14日训练赛)
A (By ggg): 题意:一个人还有x秒到红绿灯,这个红绿灯有g秒绿灯,y秒黄 灯,r秒红灯,问你到红绿灯的时候是什么灯.值得注意的是绿 灯变黄灯时,第g秒是黄灯了. B (By Anxdada) ...
- laravel扩展包服务提供者的注册的两种方式
一. 包自动发现 在 Laravel 应用的配置文件 config/app.php 中,providers 配置项定义了一个会被 Laravel 加载的服务提供者列表.当安装完新的扩展包后,在老版本中 ...
- js运行机制(线程)
浏览器线程 js运作在浏览器中,是单线程的,即js代码始终在一个线程上执行,这个线程称为js引擎线程. 浏览器是多线程的,除了js引擎线程,它还有: UI渲染线程 浏览器事件触发线程 http请求线 ...
- Java集合(六)--ArrayList、LinkedList和Vector对比
在前两篇博客,学习了ArrayList和LinkedList的源码,地址在这: Java集合(五)--LinkedList源码解读 Java集合(四)--基于JDK1.8的ArrayList源码解读 ...
- 乘法逆元-洛谷-P3811
题目背景 这是一道模板题 题目描述 给定n,p求1~n中所有整数在模p意义下的乘法逆元. 输入输出格式 输入格式: 一行n,p 输出格式: n行,第i行表示i在模p意义下的逆元. 输入输出样例 输入样 ...
- [HIHO] 1048 铺地板
历经千辛万苦,小Hi和小Ho终于到达了举办美食节的城市!虽然人山人海,但小Hi和小Ho仍然抑制不住兴奋之情,他们放下行李便投入到了美食节的活动当中.美食节的各个摊位上各自有着非常多的有意思的小游戏,其 ...
- Mysql 参数优化