Network of Schools
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 13325   Accepted: 5328

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

下面解析转自斌神的博客

强连通分量缩点求入度为0的个数和出度为0的分量个数

题目大意:N(2<N<100)各学校之间有单向的网络,每一个学校得到一套软件后,能够通过单向网络向周边的学校传输,问题1:初始至少须要向多少个学校发放软件。使得网络内全部的学校终于都能得到软件。2,至少须要加入几条传输线路(边),使随意向一个学校发放软件后,经过若干次传送,网络内全部的学校终于都能得到软件。



也就是:

— 给定一个有向图,求:



1) 至少要选几个顶点。才干做到从这些顶点出发,能够到达所有顶点



2) 至少要加多少条边。才干使得从不论什么一个顶点出发。都能到达所有顶点



解题思路:

— 1. 求出全部强连通分量

— 2. 每一个强连通分量缩成一点,则形成一个有向无环图DAG。

— 3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少

在DAG上要加几条边,才干使得DAG变成强连通的,问题2的答案就是多少

加边的方法:

要为每一个入度为0的点加入入边,为每一个出度为0的点加入出边

假定有 n 个入度为0的点,m个出度为0的点。怎样加边?

把全部入度为0的点编号 0,1,2,3,4 ....N -1

每次为一个编号为i的入度0点可达的出度0点,加入一条出边,连到编号为(i+1)%N 的那个出度0点,

这须要加n条边

若 m <= n,则

加了这n条边后。已经没有入度0点。则问题解决。一共加了n条边

若 m > n。则还有m-n个入度0点,则从这些点以外任取一点,和这些点都连上边。就可以,这还需加m-n条边。

所以,max(m,n)就是第二个问题的解

此外:当仅仅有一个强连通分支的时候,就是缩点后仅仅有一个点,尽管入度出度为0的都有一个,可是实际上不须要添加清单的项了,所以答案是1。0;

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define maxn 100 + 100
#define maxm 110 * 100
using namespace std;
int n, m;
struct node{
int u, v, next;
}; node edge[maxm]; int head[maxn], cnt;
int low[maxn], dfn[maxn];
int dfs_clock;
int Stack[maxn], top;
bool Instack[maxn];
int Belong[maxn];
int scc_clock;
int in[maxn], out[maxn];
int num[maxn]; void init(){
cnt = 0;
memset(head, -1, sizeof(head));
} void addedge(int u, int v){
edge[cnt] = {u, v, head[u]};
head[u] = cnt++;
} void getmap(){
for(int i = 1; i <= n; ++i){
int v;
while(scanf("%d", &v),v){
addedge(i, v);
}
}
} void Tarjan(int u, int per){
int v;
low[u] = dfn[u] = ++dfs_clock;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].v;
if(!dfn[v]){
Tarjan(v, u);
low[u] = min(low[u], low[v]);
}
else if(Instack[v])
low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]){
scc_clock++;
do{
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc_clock;
}
while( v != u);
}
} void suodian(){
for(int i = 1; i <= scc_clock; ++i){
out[i] = 0;
in[i] = 0;
}
for(int i = 0; i < cnt; ++i){
int u = Belong[edge[i].u];
int v = Belong[edge[i].v];
if(u != v){
out[u]++;
in[v]++;
}
}
} void find(){
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(Belong, 0, sizeof(Belong));
memset(Stack, 0, sizeof(Stack));
memset(Instack, false, sizeof(false));
dfs_clock = scc_clock = top = 0;
for(int i = 1; i <= n ; ++i){
if(!dfn[i])
Tarjan(i, i);
}
} void solve(){
if(scc_clock == 1){
printf("1\n0\n");
return ;
}
int numin, numout;
numin = numout = 0;
for(int i = 1; i <= scc_clock; ++i){
if(in[i] == 0) numin++;
if(out[i] == 0) numout++;
}
printf("%d\n%d\n", numin, max(numout, numin));
} int main (){
while(scanf("%d", &n) != EOF){
init();
getmap();
find();
suodian();
solve();
}
return 0;
}

POJ 1236--Network of Schools【scc缩点构图 &amp;&amp; 求scc入度为0的个数 &amp;&amp; 求最少加几条边使图变成强联通】的更多相关文章

  1. POJ 1236 Network of Schools Tarjan缩点

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22729   Accepted: 89 ...

  2. POJ 1236 Network of Schools (Tarjan + 缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12240   Accepted: 48 ...

  3. POJ 1236 Network of Schools —— (缩点的应用)

    题目大意:有N个学校和一些有向边将它们连结,求: 1.最少需要向几个学校发放软件,使得他们中的每一个学校最终都能够获得软件. 2.最少需要增加几条有向边使得可以从任意一个学校发放软件,使得每一个学校最 ...

  4. POJ 1236 Network of Schools 连通图缩点

    题目大意:有向图连通图,第一问求至少需要多少个软件才能传输到所有学校,第二问求至少需要增加多少条路使其成为强连通图 题目思路:利用Tarjan算法经行缩点,第一问就是求缩点后入度为0的点的个数(特殊情 ...

  5. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

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

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

  7. Poj 1236 Network of Schools (Tarjan)

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

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

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

  9. hdoj 3836 Equivalent Sets【scc&&缩点】【求最少加多少条边使图强连通】

    Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Other ...

随机推荐

  1. js滚动

    有选择性的重复造一些轮子,未必是件坏事.Aaron的博客上加了一个悬浮菜单,貌似显得很高大上了.虽然这类小把戏也不是头一次见了,但是从未自己写过.今天就选择性的拿这个功能写一写.下面是这个轮子的开发过 ...

  2. ES6 Proxy 性能之我见

    ES6 Proxy 性能之我见 本文翻译自https://thecodebarbarian.com/thoughts-on-es6-proxies-performance Proxy是ES6的一个强力 ...

  3. 使用C语言扩展Python3

    使用C语言扩展Python3.在Python3中正确调用C函数. 1. 文件demo.c #include <Python.h> // c function static PyObject ...

  4. 谷歌vimium配置

    谷歌不得不说真的是一个非常好用的浏览器(之前用的浏览器真的好low),推荐一款非常极客的的插件vimium,让你使用彻底告别鼠标,瞬间感觉高大上... 默认配置: j: 向下细微滚动窗口.  k:向上 ...

  5. Android RecyclerView、ListView实现单选列表的优雅之路.

    一 概述: 这篇文章需求来源还是比较简单的,但做的优雅仍有值得挖掘的地方. 需求来源:一个类似饿了么这种电商优惠券的选择界面: 其实就是 一个普通的列表,实现了单选功能, 效果如图:  (不要怪图渣了 ...

  6. hdu2680 Choose the best route 最短路(多源转单源)

    此题中起点有1000个,边有20000条.用链式前向星建图,再枚举起点用SPFA的话,超时了.(按理说,两千万的复杂度应该没超吧.不过一般说计算机计算速度 1~10 千万次/秒.也许拿最烂的计算机来卡 ...

  7. sql变量需要加小括号

    declare @num int select top (@num) * from A --注意,使用变量来查询的时候,单个变量需要使用()

  8. Segment公司--整合数据进行分析

    YC毕业生Segment获得1500万美元A轮融资 现在收集数据是每一个公司的必修课了,而且是从各种不同 API 上收集数据,但是你还要把这些数据整合起来才能发挥作用,Segment就能帮你整合各个平 ...

  9. 是时候学习 RxSwift 了

    相信在过去的一段时间里,对 RxSwift 多少有过接触或耳闻,或者已经积累了不少实战经验.此文主要针对那些在门口徘徊,想进又拍踩坑的同学. 为什么要学习 RxSwift 当决定做一件事情时,至少要知 ...

  10. JS 样式叠加显示

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...