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中,若两顶点间至 ...
随机推荐
- 【Leetcode】【Easy】Binary Tree Level Order Traversal
Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, ...
- March 16 2017 Week 11 Thursday
Adventure may hurt you, but monotony will kill you. 也许冒险会让你受伤,但一成不变会让你灭亡. The very theme of the univ ...
- 面条代码 vs. 馄沌代码
转载自:https://blog.csdn.net/godsme_yuan/article/details/6594013
- datatable Left and right fixed columns
$(document).ready(function() { var table = $('#example').DataTable( { scrollY: "300px", sc ...
- What is Thread
A thread is a fundamental unit of CPU utilization –a thread ID –a program counter –a register set –a ...
- POJ 3321 DFS序
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 30636 Accepted: 9162 Descr ...
- PHP设计模式——适配器模式
<?php /** * 适配器模式 * 适配器模式是将某个对象的接口适配为另一个对象所期望的接口 * * 在需要转化一个对象的接口用于另一个对象时,最好实现适配器模式对象 */ class We ...
- stixel-net绘制指标图
需解决问题: 1.离散点进行平滑曲线画法 https://blog.csdn.net/cdqn10086/article/details/70143616 def draw_curve(x,y,img ...
- c#加一个后台线程
- 【洛谷P1108】低价购买
低价购买 题目链接 n<=5000 n^2的算法是可以接受的 第一个数字显然是求最长下降子序列,可以n^2或nlognDP 要求方案数,可以在n^2算法中做一些修改,DP求方案数 dp[i]表示 ...