POJ1236_A - Network of Schools _强连通分量::Tarjan算法
| Time Limit: 1000MS | Memory Limit: 10000K |
Description
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
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
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
题意
有向图上有 N 个点,若干有向边。
第一问:至少给几个点传递信息,才能保证信息传遍整个图。
第二问:至少添加几条边,才能使任意选择点,都能传遍整个图。
思路
强连通分量的裸题。
强连通分量内的任意一点收到消息,内部其他各点必定都能收到消息。因此,可以把每个强连通分量缩成一个点。只需要考察入度为 0 的强连通分量的个数,就是第一问的答案。
对于第二问,是把图连接成一个强连通分量,同样可以在缩点后的图中操作。这里的做法是统计图中入度为0、出度为0的强连通分量的个数,取较大值即为第二问的答案。 本题中原图只有一个强连通分量的情况需要特判。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector> using namespace std; const int maxn = + ; int N;
int In[maxn], Out[maxn]; /***************************Tarjan算法模板***************************/
vector<int> G[maxn];
int Mark[maxn], Root[maxn], Stack[maxn];//时间戳,根(当前分量中时间戳最小的节点),栈
bool Instack[maxn]; //是否在栈中标记
int Ssc[maxn]; //每个节点所在的强连通分量的编号
int Index, Ssc_n, Top; //搜索时用的时间戳,强连通分量总数,栈顶指针 void Tarjan(int u) //u 当前搜索到的点
{
Mark[u] = Root[u] = ++ Index; //每找到一个点,对时间戳和根初始化
Stack[Top ++] = u; //压栈
Instack[u] = true; //在栈中标记 int v; for(int i= ; i< G[u].size(); i++) //向下搜索
{
v = G[u][i];
if(Mark[v] == ) //没到过的点
{
Tarjan(v); //先向下搜索
if(Root[u] > Root[v]) Root[u] = Root[v];//更新根
}
else if(Instack[v] && Root[u] > Mark[v]) Root[u] = Mark[v]; //到过的点且点仍在栈中,试着看这个点能不能成为根
}
/*对当前点的搜索结束*/
if(Mark[u] == Root[u]) //当前点本身时根
{
Ssc_n ++; //更新强连通分量数 do{ //栈中比它后入栈的元素在以它为根的强连通分量中
v = Stack[-- Top];
Instack[v] = false;
Ssc[v] = Ssc_n;//把同一个强连通分支的点做上相同标记
}while(v != u); //直到它自己
}
} void SSC()
{
memset(Mark, , sizeof Mark); //初始化时间戳和栈内标记
memset(Instack, false, sizeof Instack);
Index = Ssc_n = Top = ; //初始化时间戳,强连通分量数,栈顶指针 for(int i= ; i<= N; i++) //保证图上所有点都访问到
if(Mark[i] == ) Tarjan(i);
}
/***************************Tarjan算法模板***************************/ int main()
{
//freopen("in.txt", "r", stdin); scanf("%d", &N);
for(int i= ; i<= N; i++)
{
int x;
while(scanf("%d", &x), x)
G[i].push_back(x);
} SSC(); if(Ssc_n == ) //只有一个强连通分量的情况
{
cout << "1\n0\n";
return ;
} memset(In, , sizeof In); //求每个强连通分量的入度和出度
memset(Out, , sizeof Out);
for(int u= ; u<= N; u++)
{
for(int i= ; i< G[u].size(); i++)
{
int v = G[u][i];
if(Ssc[u] != Ssc[v])//u,v两点不在同一个强连通分支
Out[Ssc[u]] ++, In[Ssc[v]] ++;
}
} int S1 = , S2 = ;//找入度为0、出度为0的点的数目
for(int i= ; i<= Ssc_n; i++)
{
if(In[i] == ) S1 ++;
if(Out[i] == ) S2 ++;
} cout << S1 << endl << max(S1, S2) << endl; return ;
}
POJ1236_A - Network of Schools _强连通分量::Tarjan算法的更多相关文章
- POJ 1236 Network of Schools(强连通分量/Tarjan缩点)
传送门 Description A number of schools are connected to a computer network. Agreements have been develo ...
- 有向图强连通分量Tarjan算法
在https://www.byvoid.com/zhs/blog/scc-tarjan中关于Tarjan算法的描述非常好,转述如下: 首先解释几个概念: 有向图强连通分量:在有向图G中,如果两个顶点间 ...
- poj1236 Network of Schools【强连通分量(tarjan)缩点】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html ---by 墨染之樱花 [题目链接]http://poj.org/pr ...
- 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 (强连通分量+缩点)
题目大概: 每个学校都可以把软件复制好,交给它名单上的学校. 问题A:把软件复制成几份,然后交给不同的学校,所有学校才能够都有软件. 问题B:添加几条边,能使得这个图变成强连通图. 思路: 找出所有的 ...
- POJ 1236 Network of Schools(强连通分量)
POJ 1236 Network of Schools 题目链接 题意:题意本质上就是,给定一个有向图,问两个问题 1.从哪几个顶点出发,能走全全部点 2.最少连几条边,使得图强连通 思路: #inc ...
- 有向图强连通分量 Tarjan算法
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
- [有向图的强连通分量][Tarjan算法]
https://www.byvoid.com/blog/scc-tarjan 主要思想 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的 ...
- 图的连通性:有向图强连通分量-Tarjan算法
参考资料:http://blog.csdn.net/lezg_bkbj/article/details/11538359 上面的资料,把强连通讲的很好很清楚,值得学习. 在一个有向图G中,若两顶点间至 ...
随机推荐
- Laravel SMS 短信发送包
Laravel Sms Laravel 贴合实际需求同时满足多种通道的短信发送组件 我们基于业务需求在 overtrue/easy-sms 基础进行扩展开发,主要实现如下目标: 支持短信验证码直接在 ...
- Linux中如何安装配置Mysql和SVN服务端
目标Linux系统为centOS 一.安装登陆mysql 1.直接以root用户运行:yum install mysql 和yum install mysql-server等带安装完成. 2.安装 ...
- pl/sql中的一种链接数据库方式
今天看开发人员如此连接数据库:
- C/C++中构造函数和析构函数能否被继承
http://bbs.csdn.net/topics/390160673 标准方面做了要求的.Even though destructors are not inherited 构造函数和析构函数是不 ...
- POSIX 线程详解(经典必看)
http://www.cnblogs.com/sunminmin/p/4479952.html 总共三部分: 第一部分:POSIX 线程详解 ...
- SQL SERVER启动时间
select sqlserver_start_time,* from sys.dm_os_sys_info
- 2018.10.30 mac环境下卸载和安装mysql及安装过程遇到的一些问题解决方案
Mac下mysql的安装与卸载 配置初始化密码修改 第一:首先去官网网站下载Mysql软件 https://downloads.mysql.com/archives/community/ 记住选择对应 ...
- set 和select 的区别
简单赋值是没有区别的
- 记安卓appium自动化测试实践
一.软件安装 1. 安装node.js,安装路径D:\Program Files\nodejs\ 可以在官网下载https://nodejs.org/zh-cn/download/,版本号为node- ...
- 使用canvas上传图片+上传进度
实现效果: 速度过快,调式浏览器方式:F12 后台java代码 public String imageshangchuan(@RequestPart("xxx") Multipar ...