题目链接: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. iOS开发摇动手势实现详解

    1.当设备摇动时,系统会算出加速计的值,并告知是否发生了摇动手势.系统只会运动开始和结束时通知你,并不会在运动发生的整个过程中始终向你报告每一次运动.例如,你快速摇动设备三次,那只会收到一个摇动事件. ...

  2. iOS-自定义Log

    打印Log是一件非常消耗系统性能的事情,因此在发布时要把程序中的Log进行隐藏.以下是在iOS中自定义Log的代码 #ifdef DEBUG // 处于开发阶段 #define DJLog(...) ...

  3. Mongodb c#增删改查

    写在前面 最近项目需要,就研究了下mongodb,也是为了快速上手,就自己弄了一个简单的例子,这里记录一下. Mongodb 传统的关系数据库一般由数据库(database).表(table).记录( ...

  4. 聊下并发和Tomcat线程数(Updated)

    最近一直在解决线上一个问题,表现是: Tomcat每到凌晨会有一个高峰,峰值的并发达到了3000以上,最后的结果是Tomcat线程池满了,日志看很多请求超过了1s. 服务器性能很好,Tomcat版本是 ...

  5. Win10如何隐藏Windows Defender任务栏图标

    导读 Windows 10 至发布以来就内置集成了 Windows Defender 安全防护应用,但有许多用户平常压根儿就没注意到它的存在.微软为了使安全防护功能更加明显,Windows 10 周年 ...

  6. Capistrano SSH::AuthenticationFailed, not prompting for password

    文章是从我的个人博客上粘贴过来的, 大家也可以访问 www.iwangzheng.com 在本地执行cap deploy部署的时候会报错: connection failed for: 11.11.1 ...

  7. 入侵检测课设之Libnids开发包

    Libnids开发包介绍     Libnids是一个用于网络入侵检测开发的专业编程接口,它使用了Libpcap所以它具有捕获数据包的功能.同时,Libnids提供了TCP数据流重组功能,所以对于分析 ...

  8. WPF 路由事件总结

    1.什么是路由事件 已下为MSDN中的定义 功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件. 实现定义:路由事件是一个 CLR 事件,可以由 R ...

  9. SIFT+HOG+鲁棒统计+RANSAC

    今天的计算机视觉课老师讲了不少内容,不过都是大概讲了下,我先记录下,细讲等以后再补充. SIFT特征: 尺度不变性:用不同参数的高斯函数作用于图像(相当于对图像进行模糊,得到不同尺度的图像),用得到的 ...

  10. HDU 1285 拓普排序 基本模板例题 确定比赛名次

    确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...