[bzoj-2730][HNOI2012]矿场搭建 题解
来源:互联网 发布:魅族手机移动数据开关 编辑:程序博客网 时间:2024/05/16 11:32
题目传送门
题意解析:题目就是给了你一张无向图,让你设置任意的点为出口,然后去除任意一个点,其他点都能有一条路径到你设置的那些出口,求最少设置的出口数量。
My opinion:一开始看到这题,先随便画了几张图,然后发现了几个问题,这题可能产生环,我们都知道环上的两点之间都有两条及以上的简单路径,所以环上只需要放两个出口就好了(因为一个点没了,另一个点还在,如果只有一个出口的话,被去掉了就没了),不过这种图存在割点,不过如果一个环连着两个以上的割点,那这个环上就不需要放出口,因为如果一个割点没了,这个环上的点可以通过另外的割点到达别的出口。由这个可知,存在出口的连通块就是当每个割点都无法通过后,每个只连接一个割点的连通块。至于方案数用乘法原理,计算所有存在出口的连通块的点数之积。还有两种特殊情况,就是一个环和一条链的情况,相信如果看懂了上面所说,这两种情况很快就会想出来。(而且我已经说过一种了)
总结:
1、输入建图。
2、用tarjin求出每个割点。
3、用dfs跑每个连通块,求每个连通块的大小和连接的割点个数。
4、判断特殊情况后计算答案。
特别迷得代码:
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#define rep(i,a,n) for (int i=a;i<=n;i++)#define per(i,a,n) for (int i=a;i>=n;i--)#define Clear(a,x) memset(a,x,sizeof(a))#define sqr(x) (x)*(x)#define ll long long#define db double#define INF 200000000000000LL#define eps 1e-8using namespace std;ll read(){ ll x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}const int maxn=1005;int n,len,num,Time,m,top;int vet[maxn<<1],Next[maxn<<1],head[maxn];int dfn[maxn],low[maxn],q[maxn];int belong[maxn];ll ans;void add(int u,int v){ vet[++len]=v; Next[len]=head[u]; head[u]=len;}void dfs(int u){ dfn[u]=low[u]=++Time; for (int e=head[u];e;e=Next[e]){ int v=vet[e]; if (!dfn[v]){ dfs(v); low[u]=min(low[u],low[v]); if (low[v]>=dfn[u]) belong[u]++; }else low[u]=min(low[u],dfn[v]); }}void find(int u){ dfn[u]=low[u]=++Time; q[++top]=u; for (int e=head[u];e;e=Next[e]){ int v=vet[e]; if (dfn[v]) low[u]=min(low[u],dfn[v]); else { find(v); low[u]=min(low[u],low[v]); if (low[v]>=dfn[u]){ int t,temp=0,size=0; do{ t=q[top--]; if (belong[t]>=2) temp++; size++; }while (q[top]!=u); t=u; if (belong[u]>=2) temp++; size++; if (!temp) num+=2,ans*=size*(size-1)/2; else if (temp==1) num++,ans*=size-1; } } }}int main(){ int Cas=0; while (~scanf("%d",&m)&&m!=0){ Clear(head,0); Clear(dfn,0); Clear(belong,0); len=1; num=Time=top=0; rep(i,1,m){ int u=read(),v=read(); add(u,v);add(v,u); n=max(max(u,v),n); } rep(i,1,n) if (!dfn[i]) dfs(i); else belong[i]++; num=0; ans=1; Clear(dfn,0); rep(i,1,n) if (!dfn[i]) find(i); printf("Case %d: ",++Cas); printf("%d %lld\n",num,ans); }}
阅读全文
0 0
- [bzoj-2730][HNOI2012]矿场搭建 题解
- BZOJ 2730: [HNOI2012]矿场搭建
- BZOJ 2730 [HNOI2012]矿场搭建
- bzoj 2730 [HNOI2012]矿场搭建
- bzoj 2730: [HNOI2012]矿场搭建
- 【BZOJ】2730: [HNOI2012]矿场搭建
- BZOJ 2730: [HNOI2012]矿场搭建
- bzoj 2730: [HNOI2012]矿场搭建
- 【BZOJ】【P2730】【HNOI2012】【矿场搭建】【题解】【dfs】
- BZOJ 2730 HNOI2012 矿场搭建 Tarjan
- BZOJ 2730: [HNOI2012]矿场搭建 | tarjan
- 【连通分量】BZOJ 2730: [HNOI2012]矿场搭建
- bzoj 2730: [HNOI2012]矿场搭建 dfs
- bzoj 2730 HNOI2012 矿场搭建 tarjan
- [BZOJ]2730: [HNOI2012]矿场搭建 Tarjan求割点
- [题解]bzoj2730(HNOI2012)矿场搭建
- 2730: [HNOI2012]矿场搭建
- [割顶 乱搞] BZOJ 2730 [HNOI2012]矿场搭建
- 操作系统(一)
- 8-30 DAIRY
- 一种MFC对话框程序排错的方法
- java中的Calendar属性详解
- C++实现类似于JAVA的接口
- [bzoj-2730][HNOI2012]矿场搭建 题解
- 17-08-30 请求的转发和重定向
- html随手笔记
- Matlab函数简述
- TensorFlow 搭建mnist项目
- 使用hexo+yilia+github搭建个人博客
- C#中多线程访问winform控件的方法
- 3、重识MySQL-MySQL命令之DDL、DML、DCL
- Java集合