【强连通分量缩点】poj 1236 Network of Schools
【题意】
- 给定一个有向图,求:
- (1)至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点
- (2)至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点
【思路】
- (1)强连通分量缩点后形成一个有向无环图,只要选择入度为0的顶点,其他顶点都可以被到达
- (2)等价于一个有向无环图加最少加多少条边能够变成一个强连通图,取出度为0的点的个数和入度为0的点的个数的max,因为出度为0的点要加一条出边,入度为0的点要加一条入边
- (2)特判特殊情况:强连通分量只有一个,这时虽然入度为0和出度为0的点都是一个,但不需要加边
【AC】
- //#include<bits/stdc++.h>
- #include<iostream>
- #include<cstdio>
- #include<string>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- typedef long long ll;
- int n;
- const int maxm=;
- const int maxn=1e2+;
- struct edge
- {
- int to;
- int nxt;
- }e[maxm];
- int head[maxn],tot;
- int dfn[maxn],low[maxn],id;
- int S[maxn],top;
- int num,belong[maxn];
- bool vis[maxn];
- bool in[maxn];
- bool out[maxn];
- void init()
- {
- memset(head,-,sizeof(head));
- tot=;
- id=;
- top=;
- num=;
- memset(dfn,,sizeof(dfn));
- memset(low,,sizeof(low));
- memset(S,,sizeof(S));
- memset(vis,false,sizeof(vis));
- memset(belong,,sizeof(belong));
- memset(in,false,sizeof(in));
- memset(out,false,sizeof(out));
- }
- void addedge(int u,int v)
- {
- e[tot].to=v;
- e[tot].nxt=head[u];
- head[u]=tot++;
- }
- void tarjan(int u)
- {
- dfn[u]=low[u]=++id;
- S[++top]=u;
- vis[u]=true;
- for(int i=head[u];i!=-;i=e[i].nxt)
- {
- int v=e[i].to;
- if(!dfn[v])
- {
- tarjan(v);
- low[u]=min(low[u],low[v]);
- }
- else if(vis[v]) low[u]=min(low[u],dfn[v]);
- }
- if(dfn[u]==low[u])
- {
- num++;
- while()
- {
- belong[S[top]]=num;
- vis[S[top]]=false;
- if(S[top--]==u) break;
- }
- }
- }
- int main()
- {
- while(~scanf("%d",&n))
- {
- init();
- for(int i=;i<=n;i++)
- {
- int x;
- while()
- {
- scanf("%d",&x);
- if(x==) break;
- addedge(i,x);
- }
- }
- for(int i=;i<=n;i++)
- {
- if(!dfn[i]) tarjan(i);
- }
- for(int u=;u<=n;u++)
- {
- for(int i=head[u];i!=-;i=e[i].nxt)
- {
- int v=e[i].to;
- if(belong[u]==belong[v]) continue;
- in[belong[v]]=true;
- out[belong[u]]=true;
- }
- }
- int ans1=;
- int ans2=;
- for(int i=;i<=num;i++)
- {
- if(!in[i]) ans1++;
- if(!out[i]) ans2++;
- }
- int ans=max(ans1,ans2);
- if(num==) ans=;
- printf("%d\n%d\n",ans1,ans);
- }
- return ;
- }
【大佬博客】
www.cnblogs.com/kuangbin/archive/2011/08/07/2130277.html
解题思路:
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;
【强连通分量缩点】poj 1236 Network of Schools的更多相关文章
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)
POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意: 给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...
- POJ 1236 Network of Schools(强连通分量)
POJ 1236 Network of Schools 题目链接 题意:题意本质上就是,给定一个有向图,问两个问题 1.从哪几个顶点出发,能走全全部点 2.最少连几条边,使得图强连通 思路: #inc ...
- Poj 1236 Network of Schools (Tarjan)
题目链接: Poj 1236 Network of Schools 题目描述: 有n个学校,学校之间有一些单向的用来发射无线电的线路,当一个学校得到网络可以通过线路向其他学校传输网络,1:至少分配几个 ...
- poj 1236 Network of Schools(又是强连通分量+缩点)
http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- POJ 1236 Network Of Schools (强连通分量缩点求出度为0的和入度为0的分量个数)
Network of Schools A number of schools are connected to a computer network. Agreements have been dev ...
- POJ 1236——Network of Schools——————【加边形成强连通图】
Network of Schools Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u ...
- poj 1236 Network of Schools(连通图入度,出度为0)
http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- [tarjan] poj 1236 Network of Schools
主题链接: http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K To ...
- POJ 1236 Network of Schools(tarjan)题解
题意:一个有向图.第一问:最少给几个点信息能让所有点都收到信息.第二问:最少加几个边能实现在任意点放信息就能传遍所有点 思路:把所有强连通分量缩成一点,然后判断各个点的入度和出度 tarjan算法:问 ...
随机推荐
- php关于精准计算的模块 BCMath
Php: BCMath bc是Binary Calculator的缩写.bc*函数的参数都是操作数加上一个可选的 [int scale],比如string bcadd(string $left_ope ...
- 并查集+思维——The Door Problem
一.问题描述(题目链接) 有n个门和m个开关,每个开关可以控制任意多的门,每个门严格的只有两个开关控制,问能否通过操作某些开关使得所有门都打开.(给出门的初始状态). 二.问题分析 大部分开关问题首先 ...
- win10搭建Java环境
一.下载地址 jdk和jre官方网址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 根据你的系统选择你需要 ...
- hrbust-1545-基础数据结构——顺序表(2)
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1545 基础数据结构——顺序表(2) ...
- [Tkinter 教程] 布局管理 (Pack Place Grid)
原系列地址: Python Tkinter 简介: 本文讲述如何使用 tkinter 的布局管理 (被称作 layout managers 或 geometry managers). tkinter ...
- shell脚本,判断给出的字符串是否相等。
第一种方法[root@localhost wyb]# .sh #!/bin/bash #判断给出的字符串是否相等 read -p "Please Input a number:" ...
- mysql:破解MySQL密码的一种方法
1, 修改mysql配置文件/etc/my.cnf 12 [mysqld]skip_grant_tables 2, 重启mysql后直接用root用户登录(不用输入密码) 1 $ mysql -uro ...
- laravel 设计思想简单了解
服务容器 laravel框架中 服务容器是整个系统功能调度配置的核心,在系统运行过程中动态的为系统提供需要的服务 从而实现了解耦 控制反转(IOC) 控制反转是一种设计模式 主要解决了系统组件之间的相 ...
- 力扣题目汇总(反转字符串中的单词,EXCEL表列序号,旋置矩阵)
反转字符串中的单词 III 1.题目描述 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode ...
- python安装numpy模块
1.打开网址https://pypi.python.org/pypi/numpy,找到安装的python版本对应的numpy版本. 我的python版本是 下载的对应numpy版本是 2.将numpy ...