BZOJ2730——[HNOI2012]矿场搭建
来源:互联网 发布:centos7建站 编辑:程序博客网 时间:2024/05/16 12:24
bzoj2730 & world final 2011 H
1、题目大意:就是有一个无向图,让你在里面选择点,使得,无论哪个点没了以后,其他的点都能到达你选择的任何一个点,输出最少 选择几个点,和选择最少的方案数,最多有500条边。
2、分析:首先我们想如果没得不是割顶,那么其他的都无所谓了。
然后如果没有割顶,那就是选两个点,(避免其中你选的点没了)
如果有,我们把所有的割顶去掉,得到一些连通分量,那么如果一个连通分量里连着不止一个割顶,这个连通分量就可以去别 的连通分量里,如果只连着一个割顶,那么这个联通分量里就要选一个点了,选哪个点无所谓,因为是双联通分量啊,我不是
1、题目大意:就是有一个无向图,让你在里面选择点,使得,无论哪个点没了以后,其他的点都能到达你选择的任何一个点,输出最少 选择几个点,和选择最少的方案数,最多有500条边。
2、分析:首先我们想如果没得不是割顶,那么其他的都无所谓了。
然后如果没有割顶,那就是选两个点,(避免其中你选的点没了)
如果有,我们把所有的割顶去掉,得到一些连通分量,那么如果一个连通分量里连着不止一个割顶,这个连通分量就可以去别 的连通分量里,如果只连着一个割顶,那么这个联通分量里就要选一个点了,选哪个点无所谓,因为是双联通分量啊,我不是
把割顶都去掉了吗,最后乘法原理什么的,搞一搞就过了,交了那么多次,居然是因为最后输出没用 long long,浪费我的提交 次数,加一个优化,如果一个连通分量已经dfs到它连着超过1个更定了,就结束dfs
#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define LL long longLL head[100100], next[100100];LL u[100100], v[100100];LL pre[100010];bool iscut[100010];LL cnt1;bool vis[100010];LL dfs_clock;LL block[100010];LL cnt2;LL kk[100010], tot;bool vis_block[100010];LL dfs(LL x, LL fa){ LL lowx = pre[x] = ++ dfs_clock; LL cnt = 0; for(LL i = head[x]; i != -1; i = next[i]){ LL y = v[i]; if(!pre[y]){ cnt ++; LL lowy = dfs(y, x); lowx = min(lowx, lowy); if(lowy >= pre[x]) iscut[x] = true; } else if(pre[y] < pre[x] && y != fa){ lowx = min(lowx, pre[y]); } } if(cnt == 1 && fa < 0) iscut[x] = false; return lowx;}void solve(LL x, LL fa){ vis[x] = 1; block[x] = cnt1; for(LL i = head[x]; i != -1; i = next[i]){ LL y = v[i]; if(!vis[y]){ solve(y, x); } }}void get_ans(LL x, LL fa){ vis[x] = 1; cnt2 ++; if(cnt1 > 1) return; for(LL i = head[x]; i != -1; i = next[i]){ LL y = v[i]; if(cnt1 > 1) return; if(!vis[y]){ if(iscut[y]){ vis[y] = true; kk[++ tot] = y; cnt1 ++; continue; } get_ans(y, x); } }}int main(){ LL n; LL h = 0; while(scanf("%lld", &n) != EOF){ if(n == 0) return 0; h ++; memset(head, -1, sizeof(head)); LL m = 0; for(LL i = 1; i <= n; i ++){ scanf("%lld%lld", &u[2 * i - 1], &v[2 * i - 1]); m = max(m, u[2 * i - 1]); m = max(m, v[2 * i - 1]); u[2 * i] = v[2 * i - 1]; v[2 * i] = u[2 * i - 1]; next[2 * i - 1] = head[u[2 * i - 1]]; head[u[2 * i - 1]] = 2 * i - 1; next[2 * i] = head[u[2 * i]]; head[u[2 * i]] = 2 * i; } dfs_clock = 0; memset(iscut, 0, sizeof(iscut)); memset(pre, 0, sizeof(pre)); LL wl = dfs(1, -1); for(LL i = 1; i <= m; i ++) vis[i] = iscut[i]; for(LL i = 1; i <= m; i ++){ if(!vis[i]){ cnt1 ++; solve(i, -1); } } memset(vis, 0, sizeof(vis)); LL ans1 = 0, ans2 = 1; tot = 0; memset(vis_block, 0, sizeof(vis_block)); for(LL i = 1; i <= m; i ++){ if(!iscut[i] && !vis[i] && !vis_block[block[i]]){ cnt1 = 0; cnt2 = 0; get_ans(i, -1); if(cnt1 == 1){ ans1 ++; ans2 *= cnt2; } for(LL j = 1; j <= tot; j ++){ vis[kk[j]] = 0; } tot = 0; vis_block[block[i]] = 1; } } if(ans1 == 0) printf("Case %lld: 2 %lld\n", h, m * (m - 1) / 2); else printf("Case %lld: %lld %lld\n", h, ans1, ans2); } return 0;}
0 0
- BZOJ2730——[HNOI2012]矿场搭建
- 【BZOJ2730 || HNOI2012】矿场搭建
- bzoj2730: [HNOI2012]矿场搭建
- [BZOJ2730][HNOI2012]矿场搭建
- BZOJ2730: [HNOI2012]矿场搭建
- 【bzoj2730】[HNOI2012]矿场搭建
- bzoj2730 [HNOI2012] 矿场搭建
- [题解]bzoj2730(HNOI2012)矿场搭建
- [BZOJ2730]HNOI2012矿场搭建|割点
- 【HNOI2012】bzoj2730 矿场搭建 【解法一】
- 【HNOI2012】bzoj2730 矿场搭建 【解法二】
- BZOJ2730: [HNOI2012]矿场搭建 Tarjan求割点
- [BZOJ2730][HNOI2012]矿场搭建 Tarjan求割点
- bzoj2730 [HNOI2012]矿场搭建 (UVAlive5135 Mining Your Own Business)
- bzoj2730 [HNOI2012]矿场搭建 tarjan 点双连通分量
- bzoj2730 [HNOI2012]矿场搭建 ( 割点 & 点双连通分量 )
- bzoj2730/UVALIVE5135 矿场搭建 求割点
- 2730: [HNOI2012]矿场搭建
- C文件的基本知识
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现
- 基于OK6410的WIFI四驱小车(上)
- 系统相册访问
- ssss
- BZOJ2730——[HNOI2012]矿场搭建
- Linux 边角料(一)—— ./ 的含义
- Netty
- 【代码笔记】iOS-两个滚动条,上下都能滑动
- Android WheelView 详解
- BZOJ2466——[中山市选]树
- 一文读懂机器学习
- Java NIO框架Netty教程(一) – Hello Netty
- NYOJ 58 最少步数(dfs)