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条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太 ...
随机推荐
- 垃圾回收 GC
垃圾回收器的回收的对象: 垃圾回收只回收托管堆中的内存 什么样的对象才会被回收? 没有变量引用的对象.没有变量引用的对象,表示可以被回收了(null. 什么时间回收? 不确定,当程序需要新内存 ...
- C#图片上写文字
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Dr ...
- package.json 字段全解析 share
Name 必须字段. 小提示: 不要在name中包含js, node字样: 这个名字最终会是URL的一部分,命令行的参数,目录名,所以不能以点号或下划线开头: 这个名字可能在require()方法中被 ...
- 简单易懂的现代魔法——Play Framework攻略4
接前文:简单易懂的现代魔法——Play Framework攻略3 1.The Object 时隔2个多月,Play Framework系列又更新了,本次的主题是:利用Play Framework实现R ...
- Thread的第五天学习
1.如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如:卖票系统就可以这么做! package com.thread.demo; publi ...
- Bash的脚本参数
$0:脚本名字.此变量包含地址,可以使用basename $0获得脚本名称.$1:第一个参数$2,$3,$4,$5,…一次类推. $# 传递到脚本的参数个数$* 以一个单字符串显示所有向脚本传递的参数 ...
- NET 使用HtmlAgilityPack抓取网页数据
刚刚学习了XPath路径表达式,主要是对XML文档中的节点进行搜索,通过XPath表达式可以对XML文档中的节点位置进行快速定位和访问,html也是也是一种类似于xml的标记语言,但是语法没有那么严谨 ...
- 李洪强iOS开发之【Objective-C】08-self关键字
一.Java中的this只能用在动态方法中,不能用在静态方法中 1.在动态方法中使用this关键字 1 public class Student { 2 private int age; 3 publ ...
- Java 按字节获得字符串(中文)长度
引自:http://songjianyong.iteye.com/blog/1552973 package cn.com.songjy.test; import java.io.Unsupported ...
- 百度网盘,前几天刚从百度云改名过来,百度云这个名字给之前的百度开放云(同步盘用户比较小众)good
作者:黑郁金香链接:http://www.zhihu.com/question/51803053/answer/127562835来源:知乎著作权归作者所有,转载请联系作者获得授权. 在8月网盘大面积 ...