loj 1308(点双连通分量应用)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27016
题意:求一个连通图去掉任意一个点以及与它相连的边,图中的所有蚂蚁可以通过某些点中建造的矿井逃到地面,求最少要在图中的几个点中建造矿建,这样建造矿井的方案的总数。
思路:首先求点双连通分量,标记割点,然后我们可以分析,若一个连通分量中有且仅有一个割点,那么除了这个割点之外,别的点都能造矿井,且只需在除了这个割点之外的某个点上造一座矿井就可以了(假设破话的是这个割点,那么这个连通分量中的蚂蚁可以通过有矿井的点逃到表面,但是如果矿井恰好造在割点上,那么一旦去掉了割点之后,蚂蚁就无法逃到地面上去了(这就是为什么不选割点的原因)。至于为什么别的点可以呢,假设破话的点恰好就是有矿井的这个点,那么这个连通分量中的蚂蚁可以通过割点跑到别的点双连通分量中逃生)。然后我们就只需要找有且只有一个割点的点双连通分量有多少个就行了,然后在每个连通分量中选择任何一个不是割点的点建造矿井就行了,至于有多少种方案,也就好求了,直接连通分量的点的个数(除去割点)相乘即可。然后我想说一下为什么对于那些点连通分量中割点大于等于2的就不用选呢,其实我们画一下图就知道了,因为破话这个连通分量的任何一个点以及与它相连的边,这个连通分量的中蚂蚁还是可以通过其中一个割点跑到另一个连通分量中去逃生。这样我们就得到了割点数目等于1和大于等于2的情况,那么对于图中没有割点的情况我们应该怎么选,这也好办,画个图就明白了,只需任选两个点建造矿井就可以了,当破话了某个有矿井的点之后,蚂蚁可以通过另一个有矿井的点逃生,那么总的方案数为n*(n-1)/2。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define MAXN 22222
typedef long long ll;
typedef unsigned long long llu; struct Edge{
int v,next;
}edge[MAXN<<]; int n,m,NE;
int head[MAXN]; void Insert(int u,int v)
{
edge[NE].v=v;
edge[NE].next=head[u];
head[u]=NE++;
} int cnt,bcc_count,cut_count;
int low[MAXN],dfn[MAXN];
vector<vector<int> >blocks;
bool mark[MAXN];
bool is_cutpoint[MAXN];
stack<int>S; void Tarjan(int root,int u,int father)
{
int rt_son=;
low[u]=dfn[u]=++cnt;
mark[u]=true;
S.push(u);
for(int i=head[u];i!=-;i=edge[i].next){
int v=edge[i].v;
if(v==father)continue;
if(dfn[v]==){
Tarjan(root,v,u);
low[u]=min(low[u],low[v]);
if(u==root)rt_son++;
if(low[v]>=dfn[u]){
int x;
do{
x=S.top();
S.pop();
mark[x]=false;
blocks[bcc_count].push_back(x);
}while(v!=x);
blocks[bcc_count].push_back(u);
bcc_count++;
if(u!=root)is_cutpoint[u]=true;
}
}else if(mark[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(u==root&&rt_son>=)is_cutpoint[u]=true;
} int main()
{
int _case,u,v,t=;
scanf("%d",&_case);
while(_case--){
scanf("%d%d",&n,&m);
NE=;
memset(head,-,sizeof(head));
blocks.clear();
blocks.resize(n+);
while(!S.empty())S.pop();
while(m--){
scanf("%d%d",&u,&v);
Insert(u,v);
Insert(v,u);
}
cnt=bcc_count=;
memset(mark,false,sizeof(mark));
memset(is_cutpoint,false,sizeof(is_cutpoint));
memset(dfn,,sizeof(dfn));
Tarjan(,,-);
ll ans=;
llu ways=;
int cut_count=;
for(int i=;i<n;i++)if(is_cutpoint[i])cut_count++;
if(cut_count==){
printf("Case %d: %d %d\n",t++,,n*(n-)/);
continue;
}
for(int i=;i<bcc_count;i++){
cnt=;
for(int j=;j<blocks[i].size();j++){
int v=blocks[i][j];
if(is_cutpoint[v])cnt++;
}
if(cnt<){
ans++;
ways*=(llu)(blocks[i].size()-);
}
}
printf("Case %d: %lld %llu\n",t++,ans,ways);
}
return ; }
loj 1308(点双连通分量应用)的更多相关文章
- POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
Knights of the Round Table Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 12439 Acce ...
- 【Codefoces487E/UOJ#30】Tourists Tarjan 点双连通分量 + 树链剖分
E. Tourists time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard inpu ...
- 【BZOJ-2730】矿场搭建 Tarjan 双连通分量
2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1602 Solved: 751[Submit][Statu ...
- hihoCoder 1184 连通性二·边的双连通分量
#1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老 ...
- HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...
- 点/边 双连通分量---Tarjan算法
运用Tarjan算法,求解图的点/边双连通分量. 1.点双连通分量[块] 割点可以存在多个块中,每个块包含当前节点u,分量以边的形式输出比较有意义. typedef struct{ //栈结点结构 保 ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- poj3177 && poj3352 边双连通分量缩点
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12676 Accepted: 5368 ...
- 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)
圆桌会议必须满足:奇数个人参与,相邻的不能是敌人(敌人关系是无向边). 求无论如何都不能参加会议的骑士个数.只需求哪些骑士是可以参加的. 我们求原图的补图:只要不是敌人的两个人就连边. 在补图的一个奇 ...
随机推荐
- C++标准库异常类
C++标准库异常类 2012-12-24 16:27 5269人阅读 评论(1) 收藏 举报 分类: c/c++(36) C++标准库异常类继承层次中的根类为exception,其定义在excep ...
- 细说HTTP上篇
HTTP概述 每天,都有数以亿万计的JPEG图片.HTML页面.文本文件.MPEG电影.WAV音频文件.Java小程序和其他资源在因特网上游弋.HTTP可以从遍布全世界的Web服务器上将这些信息快速. ...
- 修改Flume-NG的hdfs sink解析时间戳源码大幅提高写入性能
Flume-NG中的hdfs sink的路径名(对应参数"hdfs.path",不允许为空)以及文件前缀(对应参数"hdfs.filePrefix")支持正则解 ...
- iOS工程如何支持64-bit(转)
苹果在2014年10月20号发布了一条消息:从明年的二月一号开始,提交到App Store的应用必须支持64-bit.详细消息地址为:https://developer.apple.com/news/ ...
- 修改Capfile,在正式环境不再使用migration修改数据库
原因是这样的,运维不开放正式环境数据库的alter权限,所以每次都要给他们把sql语句发过去, 由他们来操作. https://github.com/capistrano/rails Require ...
- cocos2d回忆
凭借自己的回忆想想看自己都学到了那些知识,这是小学的时候当初中老师的外公给我说的,现在想想,CCDirector,CCNode,CCScene,CCSprite这几个类,然后是坐标,锚点,CCNode ...
- overflow-x和overflow-y其中一个设置为visible时的奇怪现象
当overflow-x和overflow-y其中一个设置为visible时,如果另一个不是visible,那么它会被自动重置为auto 看看效果先: 第一次遇到这个问题时,我还以为是chrome的一个 ...
- 浅析django的abstract,proxy, managed
django.db.models.Model 的 Meta参数 参数 类型 说明 继承 abstract boolean 是否建表 不继承,子类自动充值为默认值(False) managed bool ...
- HTML模仿桌面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Java for LeetCode 145 Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...