<题目链接>

题目大意:

有N个学校,每个学校之间单向可以发送软件,现在给你一些学校之间的收发关系。问你下面两个问题:至少要给多少个学校发送软件才能使得最终所有学校都收到软件;至少要多加多少个关系才能使得向任意一个学校发送一套软件,每个学校都能收到软件。 

解题分析:

首先,对该图进行缩点,显然第一问问的就是,缩点后的入度为0的联通块的数量(因为这些点没有入度,必须人为的给它们软件,它们才能接收到软件);第二问,显然就是问至少要加多少条边,使得该图变为强连通图,强连通图有个条件,就是所有的点一定要有出度和入度,所以我们可以让没有出度的点连上没有入度的点,等到出度或者入度为0的点不存在时,再把出度或入度为0的点补完(不能自己连自己,因为题目要求的是最少需要多少条边,所以考虑最优情况),注意,当整张图为连通图时,它的出度和入度均为0,max(1,1)=1,但是实际上不需要补边,所以这种情况需要特判。

 #include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std; const int M = 1e5 + ;
int n, m, u, v, tot, top, cnt, col;
struct node {
int v, next;
} edge[M];
int head[M], instack[M], stk[M];
int dfn[M], low[M], belong[M],in[M],out[M];
void init() {
tot = cnt = top = col = ;
memset(stk, , sizeof(stk));
memset(head, -, sizeof(head));
memset(dfn, , sizeof(dfn));
memset(instack, , sizeof(instack));
}
void add(int u, int v) {
edge[tot].v = v,edge[tot].next = head[u];
head[u] = tot++;
}
void tarjan(int u) {
dfn[u] = low[u] = ++col; //col为遍历到该点的编号时间
instack[u] = ; //标记该元素是否在栈里
stk[top++] = u;
for (int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].u;
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (instack[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
cnt++; //记录连通块的数量
int tmp;
do{
tmp = stk[--top];
instack[tmp] = ;
belong[tmp] = cnt; //给该连通块中的点染色
} while(tmp != u) ;
}
}
void solve() {
for (int i = ; i <= n ; i++)
if (!dfn[i]) tarjan(i);
}
int main() {
while(scanf("%d", &n) != EOF) {
init();
memset(in, , sizeof(in));
memset(out, , sizeof(out));
for (int i = ; i <= n ; i++) {
int v;
scanf("%d", &v);
while(v) {
add(i, v);
scanf("%d", &v);
}
}
for (int i = ; i <= n ; i++)
if (!dfn[i]) tarjan(i);
for (int i = ; i <= n ; i++) {
for (int j = head[i] ; ~j ; j = edge[j].next) {
if (belong[edge[j].v] != belong[i]) {
in[belong[edge[j].v]]++; //统计每个连通块的出度和入度
out[belong[i]]++;
}
}
}
int sumin = , sumout = ;
for (int i = ; i <= cnt ; i++) { //遍历每个连通块
if (!in[i]) sumin++; //入度为0的连通分量个数
if (!out[i])sumout++; //出度为0的连通分量个数
}
printf("%d\n", sumin);
if (cnt == ) printf("0\n"); //如果该图已经是一个强连通图,只有一个强连通分量,则不需要加边
else printf("%d\n", max(sumin, sumout));
}
return ;
}

2018-09-30

POJ 1236 Network Of Schools 【Targan】+【缩点】的更多相关文章

  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 连通图缩点

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

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

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

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

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

  6. Poj 1236 Network of Schools (Tarjan)

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

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

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

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

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

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

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

  10. [tarjan] poj 1236 Network of Schools

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

随机推荐

  1. 使用XIB 或者storyboard 创建imageView 模式 UIViewContentModeScaleAspectFill  图片越界问题

    ImageView UIViewContentModeScaleAspectFill 超出边界的问题 代码如下 [_photoView setClipsToBounds:Yes];       sto ...

  2. Confluence 6 编辑一个站点装饰文件

    希望编辑一个站点的 decorator 文件: 进入  > 基本配置(General Configuration) > 布局(Layouts )(在Look and Feel 菜单下面) ...

  3. linux 下创建共享文件夹

    首先需要在win下共享一个盘 然后设置virtulbox 然后修改一串代码 参考原文 https://jingyan.baidu.com/article/2fb0ba40541a5900f2ec5f0 ...

  4. 【python】ftp连接,主被动,调试等级

    示例代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- import os from ftplib import FTP def ftp_down( ...

  5. Web前端渗透测试技术小结(一)

    首先端正一下态度不可干违法的事 1.SQL注入测试 对于存在SQL注入的网页,使用SQL语句进行关联查询(仿照C/S模式)eg   http://www.foo.com/user.php?id=1 常 ...

  6. [Gym-102091E] How Many Groups

    /* 先将a数组从小到大排序 dp[i][j][k]表示到以第i个数为结尾的,且第i个数改了j次,第i个数改动值为k-1的集合最大值 ans是dp过程中的最大集合大小 状态转移: 首先是到i改动为0次 ...

  7. Windows Internals 笔记——错误处理

    1.Windows函数检测到错误时,会使用一种名为“线程本地存储区”的机制将相应的错误代码与“主调线程”关联到一起.这种机制使得不同的线程能独立运行,不会出现相互干扰对方的错误代码的情况. 2.Get ...

  8. 步步为营-94-GridView中的DropDownlist值得获取与绑定

    bug场景: 例如这种"计税方式"是下拉列表的,当选择"编辑"时候,数据会丢失 修改方式,前台对应修改 后台代码在databound时候给绑定值 测试效果

  9. springboot的创建

  10. 关于The specified Android SDK Build Tools version (26.0.2) is ignored, as it is below the minimum...

    今天将项目迁移到另一台笔记本,进行build出现以下问题,导致build失败 The specified Android SDK Build Tools version (26.0.2) is ign ...