Description

A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes software (the “receiving schools”). Note that if B is in the distribution list of school
A, then A does not necessarily appear in the list of school B 

You are to write a program that computes the minimal number of schools that must receive a copy of the new software in order for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure that
by sending the copy of new software to an arbitrary school, this software will reach all schools in the network. To achieve this goal we may have to extend the lists of receivers by new members. Compute the minimal number of extensions that have to be made
so that whatever school we send the new software to, it will reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school. 

Input

The first line contains an integer N: the number of schools in the network (2 <= N <= 100). The schools are identified by the first N positive integers. Each of the next N lines describes a list of receivers. The line i+1 contains the identifiers of the receivers
of school i. Each list ends with a 0. An empty list contains a 0 alone in the line.

Output

Your program should write two lines to the standard output. The first line should contain one positive integer: the solution of subtask A. The second line should contain the solution of subtask B.

Sample Input

5
2 4 3 0
4 5 0
0
0
1 0

Sample Output

1
2

图论题目,须要解决这个问题:

1 使用Tarjan算法求子强连通图

2 标识顶点属于哪个子强连通图

3 计算各个子强连通图的零入度数和零出度数

图论中高级内容了,是有点难度的,不细心一点肯定会出错的。

这次本博主认真注解好差点儿每一个语句。希望大家能够follow我的程序。

#include <cstdio>
#include <stack>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int MAX_N = 101;//最大的顶点数
vector<int> graAdj[MAX_N];//vector表示邻接表法
int visNo[MAX_N];//记录深搜各个顶点的訪问顺序标号
int lowLink[MAX_N];//连通图的最低标识号,记录好是否递归到已经訪问过的顶点了。假设是,那么就以最低的顶点訪问顺序标号为,这样能够统一子连通图的标号。 通过推断当前最低连通图的标识号和訪问顺序号是否一致来推断是否找到了一个子强连通图
int dfsNo;//记录深搜总的訪问号
int connectNo;//当前的子强连通图的标号,终于为全部子强连通图的数量
int markNo[MAX_N];//markNo[v]代表顶点v属于子强连通图markNo[v],其值就为子强连通图
int in[MAX_N], out[MAX_N];//分别记录一个子强连通图的入度数和出度数
stack<int> stk;//深搜顶点入栈,找到子强连通图时候出栈,直到当前顶点数,全部点都属于同一个子强连通图 //深搜查找子强连通图,并记录好顶点属于哪个子强连通图
void getStrongConnected(int u)
{
visNo[u] = lowLink[u] = ++dfsNo;//第一次进入当前顶点的时候的初值
int n = (int)graAdj[u].size();
stk.push(u);
for (int i = 0; i < n; i++)//遍历当前顶点的全部连接点
{
int v = graAdj[u][i];
if (!visNo[v])//没有訪问过的时候
{
getStrongConnected(v);//递归
lowLink[u] = min(lowLink[u], lowLink[v]);//记录最低序号
}
//已经訪问过,可是还在栈里面,即还没有记录该顶点属于哪个强连通图
else if (!markNo[v]) lowLink[u] = min(lowLink[u], lowLink[v]);
}
if (visNo[u] == lowLink[u])//当前訪问顺序号等于最低标号,
{//那么就是找到了一个子强连通图
++connectNo;//每次要添加全局的连通标号
int v;
do
{
v = stk.top(); stk.pop();
markNo[v] = connectNo;//顶点对用强连通图号
} while (u != v);
}
} void Tarjan(int n)
{
//前期清零工作
dfsNo = 0, connectNo = 0;
fill(visNo, visNo+n+1, 0);
fill(lowLink, lowLink+n+1, 0);
fill(markNo, markNo+n+1, 0);
while (!stk.empty()) stk.pop(); for (int u = 1; u <= n; u++)
{
//某些顶点或许是分离的。就是图的顶点有不相连的,故此要遍历全部顶点
if (!visNo[u]) getStrongConnected(u);
}
} int main()
{
int N, u, v;
scanf("%d", &N);
for (u = 1; u <= N; u++)
{
scanf("%d", &v);
while (v)//为零表示结束
{
graAdj[u].push_back(v);//使用vector建立一个邻接表
scanf("%d", &v);
}
}
Tarjan(N);//计算子强连通图的个数,并表出各个顶点属于哪个子强连通图 for (u = 1; u <= N; u++)
{//遍历全部顶点,然后遍历顶点的邻接边。相当于遍历全部边
for (int i = 0; i < (int)graAdj[u].size(); i++)
{
int v = graAdj[u][i];
if (markNo[u] != markNo[v])//不是属于同一个子强连通图
{//分别添加该强连通图的入度和出度
out[markNo[u]]++;
in[markNo[v]]++;
}
}
} int zeroIn = 0, zeroOut = 0;
for (int i = 1; i <= connectNo; i++)
{
if (in[i] == 0) zeroIn++;
if (out[i] == 0) zeroOut++;
}
//入度为零则须要放置一个软件拷贝
printf("%d\n", zeroIn);
//变为一个强连通图,分2个情况:1 本身是一个强连通图;2 零入度或出度最大值
printf("%d\n", connectNo == 1? 0 : max(zeroIn, zeroOut)); return 0;
}

POJ 1236 Network of Schools 强连通图的更多相关文章

  1. POJ 1236 Network of Schools(强连通 Tarjan+缩点)

    POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意:  给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...

  2. Poj 1236 Network of Schools (Tarjan)

    题目链接: Poj 1236 Network of Schools 题目描述: 有n个学校,学校之间有一些单向的用来发射无线电的线路,当一个学校得到网络可以通过线路向其他学校传输网络,1:至少分配几个 ...

  3. POJ 1236 Network of Schools(强连通分量)

    POJ 1236 Network of Schools 题目链接 题意:题意本质上就是,给定一个有向图,问两个问题 1.从哪几个顶点出发,能走全全部点 2.最少连几条边,使得图强连通 思路: #inc ...

  4. poj 1236 Network of Schools(连通图入度,出度为0)

    http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  5. poj 1236 Network of Schools(又是强连通分量+缩点)

    http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  6. [tarjan] poj 1236 Network of Schools

    主题链接: http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS   Memory Limit: 10000K To ...

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

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

  8. poj 1236 Network of Schools【强连通求孤立强连通分支个数&&最少加多少条边使其成为强连通图】

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13800   Accepted: 55 ...

  9. POJ 1236 Network of Schools(Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16806   Accepted: 66 ...

随机推荐

  1. Local Response Normalization作用——对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力

    AlexNet将LeNet的思想发扬光大,把CNN的基本原理应用到了很深很宽的网络中.AlexNet主要使用到的新技术点如下. (1)成功使用ReLU作为CNN的激活函数,并验证其效果在较深的网络超过 ...

  2. Mysql数据库性能

    Mysql数据库设计规范 https://www.cnblogs.com/Luke-Me/p/8994432.html 我们在项目一开始的设计中,就要忙着考虑数据库的设计,表.字段.索引.sql等等, ...

  3. 【POJ 2417】 Discrete Logging

    [题目链接] http://poj.org/problem?id=2417 [算法] Baby-Step,Giant-Step算法 [代码] #include <algorithm> #i ...

  4. Node.js:路由

    ylbtech-Node.js:路由 1.返回顶部 1. Node.js 路由 我们要为路由提供请求的 URL 和其他需要的 GET 及 POST 参数,随后路由需要根据这些数据来执行相应的代码. 因 ...

  5. BZOJ 1485 卡特兰数 数学

    思路: 通过打表观察 这是个卡特兰数 但是它mod的数不是质数 怎么办呢 把所有数分解质因数好了 线性筛出mindiv  顺着mindiv分解质因数 复杂度$O(nlogn)$ //By Sirius ...

  6. 移动端web开发初探之Vuejs的简单实战

    这段时间在做的东西,是北邮人论坛APP的注册页.这个注册页是内嵌的网页,因为打算安卓和IOS平台同时使用.因此实际上就是在做移动端的web开发了. 在这过程中遇到了不少有意思的东西. DEMO的git ...

  7. 解决java float double 浮点型参与计算失精度

    本人前段时间做一个社区电商应用,发现了一个 天坑   ...................让我哭会 . 下面听听我的踩坑之路吧 ,电商肯定跟¥打交道了,计算少不了的.由于本人太菜 单纯的以为  fl ...

  8. 【Oracle】RAC控制文件多路复用

    1.—关闭数据库,各个节点都要关闭: [oracle@rac1 ~]$ srvctl stop database -d racdb -o immediate 2.—启动任一节点到nomount状态: ...

  9. ML二:NNSearch数据结构--二叉树

    wiki百科:http://zh.wikipedia.org/wiki/%E5%86%B3%E7%AD%96%E6%A0%91%E5%AD%A6%E4%B9%A0 opencv学习笔记--二杈决策树: ...

  10. 三维重建:QT+OpenNI+Kinect图像校正

    后记: 当时能不放弃这个方向是因为这里面涉及了一种很有效的三位场景存储方式,可能给出除图元建模之外的一种三维场景描述方式.这和Flash与位图的对比一样,基于图元的flash始终抵不过基于点描述的位图 ...