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

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. 关于jquery文件上传插件 uploadify 3.1的使用

    要使用uplaodify3.1,自然要下载相应的包,下载地址http://www.uploadify.com/download/,这里有两种包,一个是基于flash,免费的,一个是基于html5,需要 ...

  2. ubuntu12 环境下编译freerdp

    有时候需要从linux环境下远程连接到windows的环境,可以采用freerdp.freerdp是一个linux下开源的工具,在Ubuntu下可以直接用 apt-get install freerd ...

  3. AdaBoost中利用Haar特征进行人脸识别算法分析与总结1——Haar特征与积分图

    原地址:http://blog.csdn.net/watkinsong/article/details/7631241 目前因为做人脸识别的一个小项目,用到了AdaBoost的人脸识别算法,因为在网上 ...

  4. LinkedHashMap相关信息介绍(转)

    Java中的LinkedHashMap此实现与 HashMap 的不同之处在于,后者维护着一个运行于所有条目的双重链接列表.此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序 ...

  5. BI中事实表和维度表的定义

    一个典型的样例是,把逻辑业务比作一个立方体,产品维.时间维.地点维分别作为不同的坐标轴,而坐标轴的交点就是一个详细的事实.也就是说事实表是多个维度表的一个交点.而维度表是分析事实的一个窗体. 首先介绍 ...

  6. linux下自助获取帮助

    几乎所有命令都可以用 -h 或者--help参数 获取命令的使用方法帮助 man ls   也可以获取ls命令的详细帮助信息 man -k XXX  可以查看包含关键字XXX的文档 还有一个更详细的命 ...

  7. ios 上拉载入下拉刷新Dome

    为练手写了一个小的上拉载入很多其它下拉刷新的小的Dome . 没有太多的技术含量,仅仅是作为新手的启示用.是上一篇下拉载入的扩展.先看一下那个再看这个就easy非常多. Dome下载:http://d ...

  8. 1.SQL统计某张表的列数。

    select   count(syscolumns.name)    from   syscolumns   ,   sysobjects       where   syscolumns.id    ...

  9. 《TCP/IP作品详细解释2:实现》笔记--Radix树路由表

    通过IP完整的路由是路由机制,它通过搜索路由表来确定从哪个分组被发送的接口执行此,它是不一样的路由策略,路由策略 它是一组规则,这些规则可以被用来确定哪些路由编程到路由表,Net/3内核实现的路由机制 ...

  10. python语言学习9——使用list和tuple

    list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 位置 用索引来访问list中每一个位置的元素,记得索引是从0开始的,到 len-1结 ...