http://poj.org/problem?id=1236

问题概述:n所学校,它们通过单向边连接,如果A-->B表示A学校可以传递信息给B学校,那么问题来了,一:至少

要向几个学校传递信息,才能保证所有学校都能收到信息;二:至少要添加多少组关系,才能保证给任意一个学校

原始信息后,其他所有学校都能收到信息,输入第一个数表示有多少学校,后面n行,第i行第k个数表示i-->k(每行

输入到0结束)(POJ1236)

输入样例:                                      对应输出:

5                                                      1

2 4 3 0                                             2

4 5 0

0

0

1 0

两个顶点强连通:有向图G中,两个顶点可以通过某些路径互相到达

强连通图:该有向图中的任意两个顶点都强连通

强连通分量:非强连通有向图中的极大强连通子图(注意不是最大)

定理:

①当一个点既是强连通子图Ⅰ中的点,又是强连通子图Ⅱ中的点,则它是强连通子图Ⅰ∪Ⅱ中的点

②强连通分量一定由若干个环组成的

③在任何深度优先搜索中,同一强连通分量内的所有顶点均在同一棵深度优先搜索树中,也就是说,强连通分量一

定是有向图的某个深搜树子树

Trajan主要原理:

time[k]:第一次遍历到k点的时间

low[k]:k点所在强连通分量子图中第一个被搜到的点的time值

vis[k]:k点是否已经遍历

栈:每当搜索到一个点时,将它压入栈,当这个点k所有子树全部搜索完毕时,如果low[k]==time[k],说明已经找到

了一个强连通分量,将k以及在k之上的元素弹全部出栈(它们全部属于一个强连通分量,且这个强连通分量不含其

它点)

搜索过程:

→当点k有与点c相连,如果此时(time[k]时)c不在栈中,搜索c点,当c点及其子树搜索完毕回溯后,计算出

low[k] = min(low[k], low[c])

→当点k有与点c相连,如果此时(time[k]时)c在栈中,low[k] = min(low[k], time[c])

→搜索完毕后,栈内应该没有点了

期间保证:每个点每条边都只被搜索1次,且必须搜索1次,复杂度n+m,如果遍历完整个搜索树后某个点的time值

等于low值,则它是该搜索子树的根,这时,它以上(包括它自己)一直到栈顶的所有元素组成一个强连通分量,但

属于该强连通分量的所有的点low值不一定一致(但只有根节点满足low值与time值相等)

缩点过程:

→本质:将一个联通块作为一个点ltt[k]:k点属于第ltt[k]个联通块

→遍历一遍所有的边,如果边(u,v)中u和v属于不同联通块,则将它们两个所在的联通块连接在一起

题解:

设ain为缩点之后入度为0的点的个数,aout为缩点之后出度为0的点的个数,显然:这题第一个答案就是ain,第二

个答案当全图强连通时答案为0,否则为max(ain, aout)

#include<stdio.h>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
vector<int> v[105], nv[105];
stack<int> st;
int n, t, vis[105], inst[105], low[105], time[105], ltt[105], num, ain, aout, in[105], out[105];
void Trajan(int x);
int main(void)
{int i, j, x, temp;scanf("%d", &n);for(i=1;i<=n;i++){while(scanf("%d", &x), x!=0)v[i].push_back(x);}t = num = 0;for(i=1;i<=n;i++){if(vis[i]==0)Trajan(i);}for(i=1;i<=n;i++){for(j=0;j<v[i].size();j++){temp = v[i][j];if(ltt[i]!=ltt[temp])nv[ltt[i]].push_back(ltt[temp]);}}for(i=1;i<=num;i++){for(j=0;j<nv[i].size();j++)in[nv[i][j]]++, out[i]++;}ain = aout = 0;for(i=1;i<=num;i++){if(in[i]==0)ain++;if(out[i]==0)aout++;}printf("%d\n", ain);if(num==1)printf("0\n");elseprintf("%d\n", max(ain, aout));return 0;
}void Trajan(int x)
{int i, temp;st.push(x);inst[x] = vis[x] = 1;low[x] = time[x] = ++t;for(i=0;i<v[x].size();i++){temp = v[x][i];if(vis[temp]==0){Trajan(temp);low[x] = min(low[x], low[temp]);}else if(inst[temp]==1)low[x] = min(low[x], time[temp]);}if(low[x]==time[x]){num++;while(st.empty()==0){temp = st.top();st.pop();ltt[temp] = num;inst[temp] = 0;if(temp==x)break;}}
}

Trajan算法(强连通+缩点)相关推荐

  1. 强连通分量(Tarjan算法)和缩点

    强连通分量(Tarjan算法)和缩点 一些定义 给定一张有向图,对于图中任意两个节点 xxx 和 yyy ,存在从 xxx 到 yyy 的路径,也存在从 yyy 到 xxx 的路径,则称该有向图为强连 ...

  2. Tarjan算法 —— 强连通双连通缩点 模板

    TP 强连通缩点模板 双连通缩点模板 边双连通 点双连通 有向图 我们知道在一张 有向无环 图(也叫 DAG)中,肯定存在拓扑序.拓扑序的特殊顺序性质,能够允许我们在 O(n+m)O(n + m)O( ...

  3. 图论--SCC强连通缩点--Tarjan

    强连通缩点与双连通缩点大同小异,也就是说将强连通分支缩成一个点之后,没有强连通,成为有向无环图,在对图进行题目的操作. // Tarjan算法求有向图强连通分量并缩点 #include<iost ...

  4. Poj 2186 Popular Cows(Tarjan 强连通缩点)

    传送门:Poj 2186 题意:给你n头牛,m种关系,A牛认为B牛是popular的,B牛认为C牛是popular的,则A也认为C是popular的,问最终有几头被所有牛认为是popular的牛 题解 ...

  5. BZOJ1051 [HAOI2006]受欢迎的牛 Tarjan 强连通缩点

    欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1051 题意概括 有n只牛,有m个羡慕关系. 羡慕关系具有传递性. 如果A羡慕B,B羡慕C,那么我们 ...

  6. 2019ICPC(银川) - Delivery Route(强连通缩点+分块最短路)

    题目链接:点击查看 题目大意:给出n个点和m条边构成的图,每条边都有权值,其中m1条边是双向的,且权值非负,有m2条边是单向的,且权值可负,现在要求从给定起点st到其他每个点的最短路,若不存在路径则输 ...

  7. HDU - 4685 Prince and Princess(强连通缩点+二分图完备匹配)

    题目链接:点击查看 题目大意:给出n个王子和m个公主,每个王子都有喜欢的公主,题目需要我们在尽可能多的王子可以匹配到喜欢的公主的情况下,求出每个王子所能娶的所有公主,必须保证王子娶了其中任何一个之后, ...

  8. POJ - 1904 King's Quest(强连通缩点)

    题目链接:点击查看 题目大意:给出n个王子和n个公主,每个王子都有喜欢的公主,每个王子初始时都娶到了一位喜欢的公主,题目需要我们求出每个王子所能娶的所有公主,必须保证王子娶了其中任何一个之后,其他的王 ...

  9. POJ - 1236 Network of Schools(强连通缩点)

    题目链接:点击查看 题目大意:一个学校连接在一个计算机网络上,学校之间存在软件支援协议,每个学校都有它应支援的学校名单(学校A支援学校B,并不表示学校B一定支援学校A).当某校获得一个新软件时,无论是 ...

  10. 有向图缩点:tarjan强连通缩点(模板)

    SCC强连通缩点:(用之前记得init) 可以将有向图转换为一个 DAG 图,然后进行拓扑 const int N=1e4+100;const int M=1e5+100;struct Egde {i ...

最新文章

  1. 【知识碎片】Asp.Net 篇
  2. 历届试题 打印十字图(模拟)
  3. 程序员过关斩将--redis做消息队列,香吗?
  4. 产品经理经验谈100篇(二)-数据分析应用,如何构建指标体系?
  5. 50ETF期权波动率策略
  6. 查看在Ubuntu上打印的大型JSON文件
  7. matplotlib 设置标注方向_Matplotlib绘制带主题及聚类类标的散点图
  8. 多种系统负载100%方法(高可用测试、性能压测用)
  9. Linux查看kvm安装路径,Linux系统KVM虚拟化自动部署
  10. Codeforces Round #511 (Div. 1) 题解
  11. 信号与系统_冲激函数匹配法
  12. linux mysql 权限不够_linux提示权限不够怎么办
  13. 硬盘重新分区,给C盘重新分配空间
  14. 猴子偷桃(Java实现)
  15. fr4速度 微带线_微带线(microstrip)和带状线(stripline)
  16. 阿里云的各种产品都是用来干什么的?
  17. 青花瓷音乐的单片机c语言程序,c语言曲谱_单片机c语言音乐简谱代码
  18. 哈工大深圳计算机就业质量报告,多所高校公布毕业生平均年薪,南京大学和哈工大(深圳)数据亮眼...
  19. tensorflow tf.tile 使用教程·
  20. 付费系列 2 - 美式和百慕大期权 PDE 有限差分

热门文章

  1. UE4_C++_自定义细节面板_Customizing detail panels
  2. 微信小程序+“芝麻小客服”可设自动关注公众号,助力运营闭环
  3. 向量数量积公式_向量数量积公式是什么
  4. 51单片机 程序 红外发射 红外接收 红外双机通信 红外遥控器 控制 灯 系统 proteus 仿真
  5. 计算机系一班班会,天津科技大学计算机学院读书节10102i1班班会.ppt
  6. cookie—基于js的coolie使用
  7. flink不等于符号问题
  8. android 谷歌支付流程,谷歌支付怎么用 谷歌androidpay无需手机操作流程
  9. PWM原理 PWM频率与占空比详解
  10. linux查找历史记录内容,linux中查看历史记录