Graph_Master~(连通分量)

题目大意:给出m条边(隧道,无向),每条边连接两个点(矿场)。要在这些矿场中建设救援出口,防止矿场坍塌造成人员伤亡,问最少需要几个救援出口,以及对应方案数。(假设最多塌陷一个矿场)。

题解:这个题面给的数据比较良心,画画图知道需要找割点,然后把割点去掉跑连通块。也就是说每个连通块的颜色除了割点都是一样的,因为割点还属于别的连通块。紧接着就是统计答案了:

1、如果一个连通块没有割点,那么救援点至少建两个,方案数将乘上(这个连通块大小设为totv,包括割点)totv*(totv-1)/2,即C(2,totv)。建两个是以防如果只建一个,那个点坍塌了,就困死了,因为没有割点,就相当于是独立的,只能自生自灭。

2、如果一个连通块只有一个割点,那么救援点至少建一个,方案数乘上totv。因为如果割点坍塌,可以从救援点跑,如果救援点坍塌,可以从割点跑到另外的有救援点的连通块。

3、如果一个连通块有>=2个割点,不用建救援点,不用算方案数,因为不管怎么坍塌,都可以跑到别的有救援点的连通块。

(上图比较好理解)

图解:1、2、3、47、8、9、10即为仅有一个割点(割点分别为4、7)的连通块。

4、5、6、7为有两个割点(4、7)的连通块。

11、12、13、14为没有割点的连通块(独立出来的一部分)。

有了图解每个连通块应该建几个救援点,以及如何统计方案数可以说就比较清楚了。

WA了很多发,因为没有发现used[]开成了bool,而却是用于染色,应该开成int,太粗心了。可以看到数组都远超所给范围,因为前几天给坑怕了。。


#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#define clr(a,b) memset((a),(b),sizeof(a))
using namespace std; const int N = 10005;
const int M = 1e6 + 16;
typedef long long ll; struct Edge
{
int nxt, u, v;
};
Edge edge[M]; int ecnt, head[N];
int low[N], dfn[N];
int dep, col, cut_sum, totv;
int used[N], iscut[N];
int rt; void init()
{
clr(head,-1);
clr(used,0);
clr(iscut,0);
clr(dfn,0);
clr(low,0);
ecnt = dep = col = 0;
} void _add( int a, int b )
{
edge[ecnt].u = a;
edge[ecnt].v = b;
edge[ecnt].nxt = head[a];
head[a] = ecnt ++;
} void tarjan( int u, int pr )
{
low[u] = dfn[u] = ++dep;
int son = 0;
for ( int i = head[u]; i+1; i = edge[i].nxt )
{
int v = edge[i].v;
if ( v == pr ) continue;
if ( !dfn[v] )
{
son ++;
tarjan( v, u );
low[u] = min( low[u], low[v] ); if ( low[v] >= dfn[u] )
iscut[u] = 1;
}
else
low[u] = min( low[u], dfn[v] );
}
if ( u == rt && son == 1 )
iscut[u] = 0;
} void dfs( int u )
{
used[u] = col;
totv ++;
for ( int i = head[u]; i+1; i = edge[i].nxt )
{
int v = edge[i].v;
if ( iscut[v] && used[v] != col )
{
cut_sum++;
used[v] = col;
}
else if ( !used[v] )
dfs( v );
}
} int main()
{
int m;
int cas = 1;
while ( scanf("%d", &m), m )
{
int n = 0;
init();
for ( int i = 0; i < m; i ++ )
{
int u, v;
scanf("%d%d", &u, &v);
_add(u,v);
_add(v,u);
n = max( n, max(u,v) );
} for ( int i = 1; i <= n; i ++ )
{
if ( !dfn[i] )
{
rt = i;
tarjan( i, -1 );
}
} int ans1 = 0;
ll ans2 = 1;
for ( int i = 1; i <= n; i ++ )
{
if ( !used[i] && !iscut[i] )
{
totv = cut_sum = 0;
col ++;
dfs( i );
if ( cut_sum == 0 )
{
ans1 += 2;
ans2 *= 1ll*totv*(totv-1)/2;
}
else if ( cut_sum == 1 )
{
ans1 ++;
ans2 *= 1ll*totv;
}
}
} printf("Case %d: %d %lld\n", cas++, ans1, ans2);
}
return 0;
}

Graph_Master(连通分量_G_Trajan+Thought)的更多相关文章

  1. Graph_Master(连通分量_H_Trajan+拓扑序dp)

    Graph_Master_连通分量_H 题目描述: 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条 ...

  2. Graph_Master(连通分量_Poj_1904)

    Poj_1904 背景:本来是在做Voj的连通分量,做到了E( hdu_4685 ),想到了二分图,但是笔者只会最大匹配,但题目要求要输出所有的最大匹配情况,想了好久都没想出来怎么做,因为如果我已知一 ...

  3. Graph_Master(连通分量_D_Trajan缩点+dfs)

    hdu_2242 题目大意:求将一张无向图(n个点,m条边)移除一条边分为不连通两部分,使得两部分的点权和最接近,若无法分为两部分,则输出impossible. 题解:拿到题面还算清晰,就是先tarj ...

  4. Graph_Master(连通分量_A_双连通分量+桥)

    hdu 5409 题目大意:给出一张简单图,求对应输入的m条边,第i-th条边被删除后,哪两个点不连通(u,v,u<v),若有多解,使得u尽量大的同时v尽量小. 解题过程:拿到题面的第一反应缩点 ...

  5. Graph_Master(连通分量_E_Hungry+Tarjan)

    hdu_4685 终于来写了这题的解题报告,没有在昨天A出来有点遗憾,不得不说数组开大开小真的是阻碍人类进步的一大天坑. 题目大意:给出n个王子,m个公主,只要王子喜欢,公主就得嫁(这个王子当得好霸道 ...

  6. Graph_Master(连通分量_C_Trajan缩点+最小路径覆盖)

    hdu_3861 题目大意:给定一张有向图,若<u,v>可达(u可以走到v,或者 v可以走到u),则<u,v>需被划分在统一城邦,问最小划分城邦数. 题解:比较裸的题,可以看出 ...

  7. Graph_Master(连通分量_B_Trajan+完全图)

    hdu_4635 题目大意:给出一张DAG(n个点,m条边),求出能加的最大边数,使得该图无重边,无自环,非强连通. 题解:这题题面很好理解,也没有什么很难的点,主要是如何求出最大边数需要动点脑筋.首 ...

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

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

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

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

随机推荐

  1. node.js使用require给flume提交请求

      node.js使用require给flume提交请求 - 简书 https://www.jianshu.com/p/02c20e2d011a     玄月府的小妖在debug 关注 2017.04 ...

  2. FreeMarker 的使用方法

    1.FreeMarker 概述 FreeMarker 是一个用Java语言编写的模板引擎,使用模板来生成文本输出;主要用于做静态页面或页面展示; 2.FreeMarker 使用 // 导入jar包: ...

  3. 权限认证与授权(Shrio 框架)

    权限概述 认证: 系统提供的用于识别用户身份的功能, 通常登录功能就是认证功能; -- 让系统知道你是谁 授权: 系统授予用户可以访问哪些功能的证书. -- 让系统知道你能做什么! 常见的权限控制方式 ...

  4. Django接收自定义http header(转)

    add by zhj: Django将所有http header(包括你自定义的http header)都放在了HttpRequest.META这个Python标准字典中,当然HttpRequest. ...

  5. socket编程之obj压缩加密传输

    因为需要序列化这个对象以便在网络上传输.所以POJO必需要实现java.io.Serializable接口.使用了 ObjectInputStream和ObjectOutputStream来接收和发送 ...

  6. Python遇到SyntaxError: Non-ASCII character '\xe5' in file D:\eclipseworkspace\test\test_urllib2.py on line2

    写Python时遇到SyntaxError: Non-ASCII character '\xe5' in file D:\eclipseworkspace\test\test_urllib2.py o ...

  7. media query媒体查询

    媒体查询(CSS3 media query) 一.逻辑操作符:not.and.only not:not操作符用来对一条媒体查询的结果取反. and:and操作符用来把多个媒体属性组合起来,合并到同一条 ...

  8. JsonObject没有fromObject、idea引入maven有红线没依赖、JsonObject maven 依赖包

    目录: 1.JsonObject maven 依赖包 2.idea引入maven有红线,没依赖 3.JsonObject没有fromObject \\\\\\\\\\\\\\\\\\\\\\\ 1.J ...

  9. PHPCMS新闻内容调用方法介绍

    {template "content","header"} ---------- 调用根目录下phpcms\template\content\header文件 ...

  10. java知识框架

    从网上摘录的一张很经典的java学习框架图,和大家分享一下.