给我们一个有向图,有两个问题

1、最少要给多少个点发消息,才能使得所有的点都收到消息(消息可以随边传递)

2、最少需要多少条边才能使得图变成强连通图

对于一个强连通分量,可以当做一个点来考虑,所以我们可以缩点,然后得到DAG图,

那么对于第一个问,即是入度为0的点有多少个,因为入度为0的点无法收到消息。

对于第二问,只要加max(s1,s2)条边,就能使得DAG变成强连通图,  s1表示入度为0的点的个数,s2表示出度为0的点的个数

设s1 > s2, 那么首先加s2条边,这s2条边连接的是入度为0和出度为0的点,

然后剩下s1-s2个入度为0的点, 那么随便加s1-s2条边即可。

 #pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <iostream>
typedef __int64 LL;
const int INF = << ;
using namespace std;
/*
考虑如果是的一个有向图,变成连通图,
将强联通分量缩成一个点,
然后,如果某一个联通分量和其他的联通分量没有边,那么要加两条边,如果只有一条边
那么只要加1条边
*/
const int N = + ;
int dfn[N], low[N], sccno[N], dfs_clock, cnt;
stack<int> st;
vector<int> g[N]; void tarjan(int u, int fa)
{
dfn[u] = low[u] = ++dfs_clock;
st.push(u);
for (int i = ; i<g[u].size(); ++i)
{
int v = g[u][i];
if (dfn[v] == )
{
tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if (sccno[v] == )//因为有向图存在横插边,不能用横插边来更新low[u]
{
low[u] = min(low[u], low[v]);
}
}
//同样,因为强连通分量可以分布在根结点的两个分支上,所以在递归返回的时候调用
if (low[u] == dfn[u])
{
cnt++;
for (;;)
{
int x = st.top();
st.pop();
sccno[x] = cnt;
if (x == u)
break;
}
}
}
bool in[N], out[N];
int main()
{ int n;
while (scanf("%d", &n) != EOF)
{
dfs_clock = cnt = ;
while (!st.empty()) st.pop();
for (int i = ;i <= n;++i)
{
sccno[i] = ;
g[i].clear();
low[i] = dfn[i] = ;
in[i] = out[i] = false;
}
for (int i = ;i <= n;++i)
{
int u = i, v;
while (scanf("%d", &v), v)
g[u].push_back(v);
}
for (int i = ;i <= n;++i)
{
if (dfn[i] == )
tarjan(i, -);
}
for (int i = ;i <= n;++i)
{
for (int j = ;j < g[i].size();++j)
{
int v = g[i][j];
if (sccno[i] == sccno[v]) continue;
out[sccno[i]] = true;
in[sccno[v]] = true;
}
}
if (cnt == )
{
printf("1\n0\n");
continue;
}
int cnt1 = , cnt2 = ;
for (int i = ;i <= cnt;++i)
{
if (!in[i]) cnt1++;
if (!out[i]) cnt2++;
}
printf("%d\n", cnt1);
printf("%d\n", max(cnt1, cnt2));
}
return ;
}

poj1236 有向图加边变成强连通图的更多相关文章

  1. hdu1269迷宫城堡(判断有向图是否是一个强连通图)

    1 /* 题意: 给你一个图,求这个有向图示否是一个强连通图(每两个节点都是可以相互到达的)! 思路1:按正向边dfs一遍,将经过的节点计数,如果记录的节点的个数小于n,那么就说明图按照正向边就不是连 ...

  2. 有向图 加最少的边 成为强连通分量的证明 poj 1236 hdu 2767

    poj 1236: 题目大意:给出一个有向图, 任务一: 求最少的点,使得从这些点出发可以遍历整张图  任务二: 求最少加多少边 使整个图变成一个强连通分量. 首先任务一很好做, 只要缩点 之后 求 ...

  3. POJ 1236——Network of Schools——————【加边形成强连通图】

    Network of Schools Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u ...

  4. Tarjan求缩点化强连通图

    Describe: 求一个有向图加多少条边可以变成一个强连通图 Solution: Tarjan缩点染色后,判断出度和入度,所有点的出度 = 0 的和 和 入度 = 0 的和的最大值即为所求. 缩点染 ...

  5. tarjan有向图的强连通

    强连通:在有向图G中,两个顶点间至少存在一条路径,则两个点强连通. 强连通图:在有向图中,每两个顶点都强连通,则有向图G就是一个强连通图. 强连通分量:在非强连通图中的极大强连通子图,就称为强连通分量 ...

  6. [Tarjan系列] Tarjan算法与有向图的SCC

    前面的文章介绍了如何用Tarjan算法计算无向图中的e-DCC和v-DCC以及如何缩点. 本篇文章资料参考:李煜东<算法竞赛进阶指南> 这一篇我们讲如何用Tarjan算法求有向图的SCC( ...

  7. 清华集训2015-Day 1

    玛里苟斯 一个大小为 \(n\) 的可重集合 \(a\) ,求 \(\mathbb E[x^k]\) ,其中 \(x\) 为 \(a\) 的一个子集的异或和. \(n\le 10^5,1\le k\l ...

  8. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  9. dfs判断连通图(无向)

    在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点vi到顶点vj有路径相连(当然从vj到vi也一定有路径),则称vi和vj是连通的.如果 G 是有向图,那么连接vi和vj的路径中所有的边都 ...

随机推荐

  1. [知识库分享系列] 二、Web(高性能Web站点建设)

    知识库分享系列: [知识库分享系列] 二..NET(ASP.NET) [知识库分享系列] 一.开篇 分享介绍 此知识库之所以为 Web 系列,因为和 .NET 没有完全的关系,其中的技术和实践实用于各 ...

  2. flexbox语法(摘抄)

    flex 容器上的属性: flex-direction: row | row-reverse | column | column-reverse (项目的排列方向) flex-wrap : nowra ...

  3. Aerospike | Aerospike Chinese

    Aerospike | Aerospike Chinese 如果您的企业依赖于: 庞大的数据量(超过任何结构化数据库所能处理的数据量) 可预见(且快速)的性能 透明的扩展 始终正常运行 那么您只有一个 ...

  4. Velocity教程-脚本语法详解(转)

    Velocity是一个基于java的模板引擎(template engine).它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象. 当Veloci ...

  5. 6.0RMB MP3所看到的……

    产品篇:          偶然看到这个商品信息,作为电子开发人员,首先想到的便是采用了哪家芯片方案,怎么做到这么低的价格!     于是立刻买了一台回来,拆机如下:          成本BOM: ...

  6. Unable to instantiate activity ComponentInfo或java.lang.ClassNotFoundException: com.ibright.herolegen

    不知道怎么回事,在libs中添加了jar包后,无法给jar包附加上源码,于是采取以下措施: 删除自动生成的依赖: 在Android Dependences目录上右击->Build Path -& ...

  7. 关于sizeof的笔试面试题具体解释

    原创Blog,转载请注明处处 http://blog.csdn.net/hello_hwc 注意:sizeof是编译期计算出结果的,这一点对后面的理解非常重要 一.关于结构体 先看下代码 #inclu ...

  8. Swift - 文本标签(UILabel)的用法

    1,标签的创建 1 2 3 4 5 6 7 8 9 10 import UIKit class ViewController: UIViewController {     override func ...

  9. [C#基础] 继承

    虚方法和覆写方法 虚方法可以使基类的引用访问"升至"派生类中 可以使用基类引用调用派生类的方法,只需满足下面的条件 派生类的方法和基类的方法有相同的签名和返回类型 基类的方法使用v ...

  10. [Android学习笔记]ShareSDK的使用

    ShareSDK使用方便,集成简单,正式客户端开发人员的首选组件 集成步骤,使用说明见官方文档: http://wiki.sharesdk.cn/Android_快速集成指南 记录: 直接使用官方De ...