题目链接: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(点双连通分量应用)的更多相关文章

  1. POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]

    Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 12439   Acce ...

  2. 【Codefoces487E/UOJ#30】Tourists Tarjan 点双连通分量 + 树链剖分

    E. Tourists time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard inpu ...

  3. 【BZOJ-2730】矿场搭建 Tarjan 双连通分量

    2730: [HNOI2012]矿场搭建 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1602  Solved: 751[Submit][Statu ...

  4. hihoCoder 1184 连通性二·边的双连通分量

    #1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老 ...

  5. 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 ...

  6. 点/边 双连通分量---Tarjan算法

    运用Tarjan算法,求解图的点/边双连通分量. 1.点双连通分量[块] 割点可以存在多个块中,每个块包含当前节点u,分量以边的形式输出比较有意义. typedef struct{ //栈结点结构 保 ...

  7. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  8. poj3177 && poj3352 边双连通分量缩点

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12676   Accepted: 5368 ...

  9. 【POJ 2942】Knights of the Round Table(点双连通分量,二分图染色)

    圆桌会议必须满足:奇数个人参与,相邻的不能是敌人(敌人关系是无向边). 求无论如何都不能参加会议的骑士个数.只需求哪些骑士是可以参加的. 我们求原图的补图:只要不是敌人的两个人就连边. 在补图的一个奇 ...

随机推荐

  1. SQL触发器

    1. 创建一个触发器,当一本书被还回时,从LOAN表中删除相应的借阅记录,将该学生借阅这本书记录添加到LoadHist表中:并检查是否有用户在等待预约这本书,如有则将这本书的借阅状况修改为 已经预约: ...

  2. [整理]iOS开发学习

    最近想趁着休假,花点时间了解下最新的iOS8下的新特性以及Swift语言(想大致了解下和Objective-C有了哪些改进和不同) 可以通过Chris Lattner:Swift 编程语言首席架构师初 ...

  3. 后台返回json数据,前台显示代码

    List list = "从DAL获取的数据集合" //取出分页标签html int pageIndex = context.Request["pageIndex&quo ...

  4. 一个Java对象到底占用多大内存?

    最近在读<深入理解Java虚拟机>,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存? 在网上搜到了一篇博客讲的非常好 ...

  5. XML做下拉列表

    5-18X.php主页面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...

  6. Mysql跨平台(Windows,Linux,Mac)使用与安装

    MySQL其实是一个跨平台的轻量级数据库,平时开发会用到很多.有写程序可能要跨平台开发,接下来我就介绍一下如何跨平台使用Mysql. 这里所谓的跨平台就是Windows,Linux,Mac共同用一套M ...

  7. 新鲜出炉的百度js面试题

    (文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 最近两位同学入职百度,带回来的笔试题基本上毫无悬念,不过有一个小题看到让人忍不住笑出声来,真的很无聊 ...

  8. 使用JDBC获取各数据库的Meta信息——表以及对应的列

    先贴代码,作为草稿: 第一个是工具类, MapUtil.java [java] view plain copy import java.util.ArrayList; import java.util ...

  9. 为nginx增加nginx_http_concat模块

    为nginx增加nginx_http_concat模块 时间 2013-06-05 22:14:56  我行我思 原文  http://www.fanjun.me/?p=562 主题 Nginx 缘由 ...

  10. GIT的标准文档 使用和服务介绍

    http://www.kancloud.cn/kancloud/how-to-use-github/42192 1. 探索GitHub 熟悉Git的人几乎都知道并喜欢GitHub,反过来GitHub也 ...