HDU 3844 Mining Your Own Business(割点,经典)
题意:
给出一个连通图,要求将某些点涂黑,使得无论哪个点(包括相关的边)撤掉后能够成功使得剩下的所有点能够到达任意一个涂黑的点,颜料不多,涂黑的点越少越好,并输出要涂几个点和有多少种涂法。
思路:
要使得任意撤掉一个点都能使其他点能够到达黑点,那么点双连通分量能保证这点,那么就在同个点双连通分量内涂黑1个点。但是每个【点双连通分量】都涂吗?太浪费颜料了,那就缩点成树,只需要涂叶子即可,那就找度为1的缩点。但是种数呢?叶子内的点除了割点外都是可以涂黑的,因为如果黑色割点被撤掉,那么叶子中的其他点怎么办?所以不能涂割点,每个黑点有【叶子中的点数-1】种涂法,所有黑店的涂法相乘为第2个结果。
特殊情况,因为给的是连通图且至少有2个点,那么还可能会出现没有割点的情况(仅1个点双连通分量),那就直接涂黑两个,以防一个黑点被撤掉。
此题出现的连续的点可能多达10万个,DFS就会爆栈。在C++下可以手动开栈,G++下的还不清楚怎么开。
#pragma comment(linker,"/STACK:102400000,102400000")//开栈
//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <stack>
#define LL long long
#define pii pair<int,int>
using namespace std;
const int N=+;
const int INF=0x7f7f7f7f;
int up;
int low[N], dfn[N];
bool iscut[N];
int dfn_clock, bcc_cnt, bcc_no[N];
unordered_map<int,int> mapp;
stack< pii > stac;
vector<int> bcc[N], vect[N]; void DFS(int x, int far)//tarjan
{
dfn[x]=low[x]=++dfn_clock; int chd=;
for(int i=; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!dfn[t])
{
chd++;
stac.push(make_pair(x,t));
DFS(t,x);
low[x]=min( low[x], low[t]);
if(low[t]>=dfn[x])
{
iscut[x]=true; //需要标记割点
bcc[++bcc_cnt].clear();
while(true)
{
int a=stac.top().first;
int b=stac.top().second;
stac.pop();
if(bcc_no[a]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(a);
bcc_no[a]=bcc_cnt;
}
if(bcc_no[b]!=bcc_cnt)
{
bcc[bcc_cnt].push_back(b);
bcc_no[b]=bcc_cnt;
}
if(a==x&&b==t) break;
}
}
}
else if( dfn[t]<dfn[x] && t!=far)
{
stac.push(make_pair(x,t));
low[x]=min(low[x],dfn[t]);
}
}
if(chd==&&far==) iscut[x]=false; //根
} void find_bcc(int Case)
{
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(iscut,,sizeof(iscut));
memset(bcc_no,,sizeof(bcc_no)); dfn_clock=bcc_cnt=;
for(int i=; i<=up; i++) if(!dfn[i]) DFS(i,); //深搜
LL ans1=,ans2=; for(int i=; i<=bcc_cnt; i++) //统计度为多少
{
int cnt=;
for(int j=; j<bcc[i].size(); j++) if(iscut[bcc[i][j] ]) cnt++; //有割点就统计连通分量i的度。
if(cnt==) ans1++, ans2*=bcc[i].size()-;
}
if(bcc_cnt==) ans1=,ans2=(LL)bcc[].size()*(bcc[].size()-)/;
printf("Case %d: %lld %lld\n", Case, ans1, ans2);
} int main()
{
freopen("input.txt", "r", stdin);
int a, b, n, j=;
while(scanf("%d",&n), n)
{
mapp.clear();
for(int i=; i<N; i++) vect[i].clear();
up=;
for(int i=; i<n; i++)
{
scanf("%d%d",&a,&b);
if(!mapp[a]) mapp[a]=++up;
if(!mapp[b]) mapp[b]=++up;//点号缩小为连续 vect[mapp[a]].push_back(mapp[b]);
vect[mapp[b]].push_back(mapp[a]);
}
find_bcc(++j);
}
return ;
}
AC代码
HDU 3844 Mining Your Own Business(割点,经典)的更多相关文章
- HDU 3844 Mining Your Own Business
首先,如果图本来就是一个点双联通的(即不存在割点),那么从这个图中选出任意两个点就OK了. 如果这个图存在割点,那么我们把割点拿掉后图就会变得支离破碎了.对于那种只和一个割点相连的块,这个块中至少要选 ...
- UVALive - 5135 - Mining Your Own Business(双连通分量+思维)
Problem UVALive - 5135 - Mining Your Own Business Time Limit: 5000 mSec Problem Description John D ...
- HDU3844 Mining Your Own Business
HDU3844 Mining Your Own Business 问题描述John Digger是一个大型illudium phosdex矿的所有者.该矿山由一系列隧道组成,这些隧道在各个大型交叉口相 ...
- 「题解报告」SP16185 Mining your own business
题解 SP16185 Mining your own business 原题传送门 题意 给你一个无向图,求至少安装多少个太平井,才能使不管那个点封闭,其他点都可以与有太平井的点联通. 题解 其他题解 ...
- HDU 2181 哈密顿绕行世界问题(经典DFS+回溯)
哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- HDU 3038 - How Many Answers Are Wrong - [经典带权并查集]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3038 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- HDU 1789 Doing Homework again(非常经典的贪心)
Doing Homework again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- HDU 1180 诡异的楼梯(超级经典的bfs之一,需多回顾)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1180 诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others) ...
- UVA5135 Mining Your Own Business ( 无向图双连通分量)
题目链接 题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太 ...
随机推荐
- spring mvc 数据绑定总结
spring mvc 做web开发时,经常会不知道如何合适绑定页面数据.用惯struts2的朋友更认为spring mvc 绑定数据不如struts2方便(本人最开始也是这么认为),经过一段时间的应用 ...
- Pyp 替代sed,awk的文本处理工具
Linux上文本处理工具虽不少,像cut,tr,join,split,paste,sort,uniq,sed,awk这些经典工具让人眼花缭乱,而且都太老了,使用方法都不太人性化,尤其awk,语法简直反 ...
- CF 295A Greg and Array (两次建树,区间更新,单点查询)
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm& ...
- C# 面向对象之概念理解
什么是对象? <韦氏大词典>中对对象定义: (1)某种可为人所感知的物质. (2)思维.感受或动作所作用的物质或精神体. ----说白了万物皆对象 熟悉的对象描述: 对象就是客观世界中的物 ...
- SDUT1466双向队列
http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=1466&cid=1182 题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列 ...
- lintcode : 二叉树的层次遍历II
题目 二叉树的层次遍历 II 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, ...
- java中什么时候该用static修饰方法?有什么好处或者坏处?
当一个方法或者变量需要初始化加载,或者是经常被调用的时候可以加上static.用static修饰的方法可以用类名直接调用,不用的一定要先实例化一个对象然后才可以调用比如 person这个类里面有一个方 ...
- Hibernate逍遥游记-第12章 映射值类型集合-004映射Map(<map-key>)
1. 2. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate ...
- Google不做坏事吗?
说中国足球为什么冲不出亚洲,那是因为咱中国人太文气,足球是种“斗牛士”式的游戏,得玩的有点儿“野蛮”色彩.记得以前在英国的时候,遇上联赛,晚上大街小巷全民皆兵,曼切斯特队的粉丝在街道一边酒吧里,利物浦 ...
- QT进度条QProgressBar的练习(定制QProgressBar,单独成为一个控件)
progressbar.h #ifndef PROGRESSBAR_H #define PROGRESSBAR_H #include <QProgressBar> class QStrin ...