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(点双连通分量,二分图染色)
圆桌会议必须满足:奇数个人参与,相邻的不能是敌人(敌人关系是无向边). 求无论如何都不能参加会议的骑士个数.只需求哪些骑士是可以参加的. 我们求原图的补图:只要不是敌人的两个人就连边. 在补图的一个奇 ...
随机推荐
- 文件系统:drbd主备服务器文件同步
一. DRBD介绍 DRBD是一种块设备,可以被用于高可用(HA)之中.它类似于一个网络RAID-1功能.当你将数据写入本地 文件系统时,数据还将会被发送到网络中另一台主机上.以相同的形式记录在一个文 ...
- Linux下链接mysql数据库的命令
一.MySQL 连接本地数据库,用户名为“root”,密码“123”(注意:“-p”和“123” 之间不能有空格) C:\>mysql -h localhost -u root -p123 二. ...
- Zhulina 的高分子刷理论
高分子刷的解析平均场理论有两种表述方式.一个是MWC理论(Macromolecules 1988, 21, 2610-2619),另外一个就是Zhulina和Birshtein这两位俄罗斯老太太的理论 ...
- Python字符串基础操作
==============字符串======== >>> s1='www.baidu.com' >>> type(s1) <type 'str'> & ...
- js实现把网页table导成Excel
//导出excel function exportExcel(DivID,strTitle){ if(DivID==null) { return false; } var jXls, myWorkbo ...
- sql把表格拼成字符串,多半使用于GROUP BY
--假定要聚合的字段是id ,要统计的字段是tname --select a.tname from @T1 a for xml path('row') select id,REPLACE(replac ...
- 滑动菜单栏(一)开源项目SlidingMenu的使用
本帖最后由 user1 于 2013-7-16 21:56 编辑 一.SlidingMenu简介相信大家对SlidingMenu都不陌生了,它是一种比较新的设置界面或配置界面的效果,在主界面左滑或者右 ...
- [Effective JavaScript 笔记]第17条:间接调用eval函数优于直接调用
eval函数不仅仅是一个函数.大多数函数只访问定义它们所在的作用域,而不能访问除此之外的作用域(词法作用域).eval函数具有访问调用它时的整个作用域的能力.编译器编写者首次设法优化js时,eval函 ...
- [Effective JavaScript 笔记]第53条:保持一致的约定
对于api使用者来说,你所使用的命名和函数签名是最能产生普遍影响的决策.这些约定很重要具有巨大的影响力.它建立了基本的词汇和使用它们的应用程序的惯用法.库的使用者必须学会阅读和使用这些.一致的约定可以 ...
- ZeroMQ之Push与Pull (Java)
本系列文章均转自:http://blog.csdn.net/kobejayandy/article/details/20163431 在ZeroMQ中并没有绝对的服务端与客户端之分,所有的数据接收与发 ...