Network of Schools
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 13804   Accepted: 5507

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

Source

 
题意:

N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。2,至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

也就是:给定一个有向图,求:

1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点

2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点

思路:先求出所有连通分量,将每个连通分量缩成一点,则形成一个有向无环图DAG。为题1的答案就是DAG中入度为0的点个数。问题2等价于在DAG中最少加几条边才能变成强连通。

要为每个入度为0的点加入边,为每个出度为0的点加出边,假设有n个入度为0的点,m个出度为0的点,则答案一定是min(n, m)。另外需要注意的是如果整个图只有一个强连通分支的时候,即缩点后只有一个点,则不需要加边,输出0。

/*
ID: LinKArftc
PROG: 1236.cpp
LANG: C++
*/ #include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <utility>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define eps 1e-8
#define randin srand((unsigned int)time(NULL))
#define input freopen("input.txt","r",stdin)
#define debug(s) cout << "s = " << s << endl;
#define outstars cout << "*************" << endl;
const double PI = acos(-1.0);
const double e = exp(1.0);
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
typedef long long ll; const int maxn = ;
const int maxm = ; struct Edge {
int v, next;
} edge[maxm]; int tot, head[maxn]; void init() {
tot = ;
memset(head, -, sizeof(head));
} void addedge(int u, int v) {
edge[tot].v = v;
edge[tot].next = head[u];
head[u] = tot ++;
} int n, m; int dfn[maxn], low[maxn], ins[maxn], belong[maxn];
int scc, Time;
stack <int> st;
vector <int> vec[maxn]; void tarjan(int u) {
dfn[u] = low[u] = ++ Time;
int v;
st.push(u);
ins[u] = true;
for (int i = head[u]; i + ; i = edge[i].next) {
v = edge[i].v;
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (ins[v]) low[u] = min(low[u], low[v]);
}
if (low[u] == dfn[u]) {
scc ++;
do {
v = st.top();
st.pop();
ins[v] = false;
vec[scc].push_back(v);
belong[v] = scc;
} while (u != v);
}
} int indeg[maxn], outdeg[maxn]; int main() {
//input;
int v;
while (~scanf("%d", &n)) {
init();
for (int i = ; i <= n; i ++) {
while (~scanf("%d", &v) && v) {
addedge(i, v);
}
}
while (!st.empty()) st.pop();
for (int i = ; i <= n; i ++) vec[i].clear();
memset(dfn, , sizeof(dfn));
memset(ins, , sizeof(ins));
Time = ;
scc = ;
for (int i = ; i <= n; i ++) {
if (!dfn[i]) tarjan(i);
}
memset(indeg, , sizeof(indeg));
memset(outdeg, , sizeof(outdeg));
for (int u = ; u <= n; u ++) {
for (int i = head[u]; i + ; i = edge[i].next) {
v = edge[i].v;
if (belong[u] == belong[v]) continue;
outdeg[belong[u]] ++;
indeg[belong[v]] ++;
}
}
int incnt = , outcnt = ;
for (int i = ; i <= scc; i ++) {
if (indeg[i] == ) incnt ++;
if (outdeg[i] == ) outcnt ++;
}
printf("%d\n", incnt);
if (scc == ) printf("0\n");
else printf("%d\n", max(incnt, outcnt)); } return ;
}

POJ1236 (强连通分量缩点求入度为0和出度为0的分量个数)的更多相关文章

  1. POJ 1236 Network Of Schools (强连通分量缩点求出度为0的和入度为0的分量个数)

    Network of Schools A number of schools are connected to a computer network. Agreements have been dev ...

  2. POJ 1236 Network of Schools (强连通分量缩点求度数)

    题意: 求一个有向图中: (1)要选几个点才能把的点走遍 (2)要添加多少条边使得整个图强联通 分析: 对于问题1, 我们只要求出缩点后的图有多少个入度为0的scc就好, 因为有入度的scc可以从其他 ...

  3. Tarjan缩点求入度为零的点的个数问题

    Description: 一堆人需要联系,但如果x 可以联系 y,你联系了x就不用联系y了,你联系一个人都会有固定的花费,问你最小联系多少人,和最小花费 Solution: Tarjan缩点,求出缩点 ...

  4. POJ1236 强连通 (缩点后度数的应用)

    题意:       一些学校有一个发送消息的体系,现在给你一些可以直接发送消息的一些关系(单向)然后有两个问题 (1) 问你至少向多少个学校发送消息可以让所有的学校都得到消息 (2) 问至少加多少条边 ...

  5. poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11047   Accepted: 4725 ...

  6. POJ1236Network of Schools(强连通分量 + 缩点)

    题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...

  7. POJ 2186 Popular Cows(强连通分量缩点)

    题目链接:http://poj.org/problem?id=2186 题目意思大概是:给定N(N<=10000)个点和M(M<=50000)条有向边,求有多少个“受欢迎的点”.所谓的“受 ...

  8. 缩点+出入度 poj1236

    题目链接:https://vjudge.net/contest/219056#problem/H 题意:先输入n,代表接下来有n个点,接下来n行,第i行里面的数(假设是)a,b...0(到0表示结束) ...

  9. 【强连通分量缩点】poj 1236 Network of Schools

    poj.org/problem?id=1236 [题意] 给定一个有向图,求: (1)至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 (2)至少要加多少条边,才能使得从任何一个顶点出发,都 ...

随机推荐

  1. 第六篇 常用请求协议之post put patch 总结

    [转]https://blog.csdn.net/sshfl_csdn     感谢愿意总结分享的人,thanks idempotent 幂等的 如果一个方法重复执行多次,产生的效果是一样的,那就是i ...

  2. 腾讯云,搭建 FTP 文件服务

    腾讯云,搭建 FTP 文件服务 腾讯云,搭建 FTP 文件服务 安装并启动 FTP 服务 任务时间:5min ~ 10min 安装 VSFTPD 使用 yum 安装 vsftpd: yum insta ...

  3. c++调用Python基础功能

    c++调用Python首先安装Python,以win7为例,Python路径为:c:\Python35\,通过mingw编译c++代码.编写makefile文件,首先要添加包含路径:inc_path ...

  4. 启动 SQL Server 管理 Studio 在 SQL Server 2008R2 中的错误消息:"无法读取此系统上以前注册的服务器的列表" 解决方法

    问题: 服务器被人直接停掉,重启后,发现sqlserver2008r2 启动管理器报错: "无法读取此系统上以前注册的服务器的列表" 如图: 点击继续,进入后: 解决方法: 点击上 ...

  5. spring-data-jpa 简单使用心得

    对于总是使用mybatis的我,突发奇想的想使用spring-data-jpa搭一个小环境,这几天处处碰壁,现总结如下: 环境采用springboot maven需要导入: <dependenc ...

  6. Python标准模块logging

    http://blog.csdn.net/fxjtoday/article/details/6307285 开发Python, 一直以来都是使用自己编写的logging模块. 比较土...... 今天 ...

  7. lintcode-135-数字组合

    135-数字组合 给出一组候选数字(C)和目标数字(T),找到C中所有的组合,使找出的数字和为T.C中的数字可以无限制重复被选取. 例如,给出候选数组[2,3,6,7]和目标数字7,所求的解为: [7 ...

  8. Win10 1803安装Ubuntu1804子系统

    1.win10应用商店选择Ubuntu1804安装 点击打开会提示https://docs.microsoft.com/zh-cn/windows/wsl/install-win10 2.用管理员po ...

  9. JAVA调用Oracle存储过程和函数

    连接数据库的工具类: import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; imp ...

  10. BZOJ4347 POI2016Nim z utrudnieniem(博弈+动态规划)

    由nim游戏的结论,显然等价于去掉一些数使剩下的数异或和为0. 暴力的dp比较显然,设f[i][j][k]为前i堆移走j堆(模意义下)后异或和为k的方案数.注意到总石子数量不超过1e7,按ai从小到大 ...