求有向图的强连通分量     Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记. (1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序.以下图为例: G图 结点第二次被访问即为退出之时,那么我们可以得到结点的退出顺序 (2)倒转每一条边的方向,构造出一个反图G’.然后按照退出顺序的逆序对反图进行第二次DFS遍历.我们按1.4.2.3.5的逆序第二次DFS遍历: G`图   访问过程如下: 每次遍历得到的那些点即属于同一个强连通分量…
在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的定义: 若在有向图G中 存在u到v的路径的同时也存在v到u的路径 则称u与v是强连通的 若G中所有点之间两两之间是强连通的则称G为一个强连通图 一个有向非强连通图的极大强连通子图称为强连通分量 极大强连通子图:G是一个极大强连通子图 当且仅当G是一个强连通图 同时不存在另一个强连通图G'使G是它的真…
百度百科 https://baike.baidu.com/item/tarjan%E7%AE%97%E6%B3%95/10687825?fr=aladdin 参考博文 http://blog.csdn.net/qq_34374664/article/details/77488976 http://blog.csdn.net/mengxiang000000/article/details/51672725 https://www.cnblogs.com/shadowland/p/5872257.h…
算法描述 tarjan算法思想:从一个点开始,进行深度优先遍历,同时记录到达该点的时间(dfn记录到达i点的时间),和该点能直接或间接到达的点中的最早的时间(low[i]记录这个值,其中low的初始值等于dfn).如图: 假设我们从1开始DFS,那么到达1的时间为1,到达2的时间为2,到达3的时间为3.同时,点1能直接或间接到达的点中,最小时间为1,点2能通过3间接到达点1,所以点2可到达最早的点时间为1,点3可以直接到达点1,故点3到达的最早的点的时间为1.).对于每一个没有被遍历到的点A,如…
tarjan算法是在dfs生成一颗dfs树的时候按照访问顺序的先后,为每个结点分配一个时间戳,然后再用low[u]表示结点能访问到的最小时间戳 以上的各种应用都是在此拓展而来的. 割点:如果一个图去掉某个点,使得图的连通分支数增加,那么这个点就是割点 某个点是割点,当且仅当这个点的后代没有连回自己祖先的边.即low[v] >= dfn[u]     , v是u的后代 需要注意的是根结点的特判,因为根结点没有祖先,根结点是割点,当且仅当根结点有两个以上的儿子. 问题:重边对该算法有影响吗?没有影响…
有向图的连通分量的求解思路 kosaraju算法 逛了很多博客,感觉都很难懂,终于找到一篇能看懂的,摘要记录一下 原博客https://www.cnblogs.com/nullzx/p/6437926.html 关于连通分量是什么自行百度,这里主要说明连通分量的求解方法 基本思路:第一次DFS得出顶点的顺序,根据顶点顺序进行第二次DFS,也就是逆后序遍历(手动模拟一下堆栈就知道第二次DFS的过程就能得出答案). 为什么要两次DFS? 如果从连通分量A中任意一个定点DFS,得不到正确结果.应该按照…
用十字链表结构写的,根据数据结构书上的描述和自己的理解实现.但理解的不透彻,所以不知道有没有错误.但实验了几个都ok. #include <iostream> #include <vector> using namespace std; //有向图十字链表表示 #define MAX_VERTEX_NUM 20 typedef struct ArcBox{ int tailvex, headvex; //该弧尾和头顶点的位置 struct ArcBox *hlink, *tlink…
代码: #include<cstdio> #include<cstring> #include<iostream> using namespace std; ][],nmap[][]; ]; ,aaa=,n,m,post[]; void dfs(int); void ndfs(int); int main() { scanf("%d%d",&n,&m); ;i<=m;i++){ int x,y; scanf("%d%d…
接上一节 Tarjan算法初探(1):Tarjan如何求有向图的强连通分量 Tarjan算法一个非常重要的应用就是 在一张题目性质在点上性质能够合并的普通有向图中将整个强连通分量视作一个点来把整张图变成一张DAG(即有向无环图) 而DAG的形态满足最优子结构经常与DP联系在一起 故缩点常作为一条桥梁将图论与DP相联系 缩点思想不难理解 这里主要说明一下代码的操作细节与流程: 1.使用Tarjan算法求出每个点属于哪一个强连通分量 2.枚举每一条点将每一个点对应性质合并到新的点上 3.枚举每一条边…
文字描述 有向图强连通分量的定义:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量(strongly connected components). 用深度优先搜索求有向图的强连通分量的方法如下并假设有向图的存储结构为十字链表. 1 在有向图G上,从某个定点出发沿以该顶点为尾的弧…
接上一节Tarjan算法初探(2):缩点 在此首先提出几个概念: 割点集合:一个无向连通图G 若删除它的一个点集 以及点集中所有点相连的边(任意一端在点集中)后 G中有点之间不再连通则称这个点集是它的一个割点集合 割边集合:一个无向连通图G 若删除它的一个边集 G中有点之间不再连通则称这个边集是它的一个割边集合 图的点联通度:无向连通图的最小割点集合中元素的个数是一张无向连通图的点连通度 图的边联通度:无向连通图的最小割边集合中元素的个数是一张无向连通图的边联通度 割点:如果一个无向连通图的点连…
有向图的强连通分量 定义:在有向图\(G\)中,如果两个顶点\(v_i,v_j\)间\((v_i>v_j)\)有一条从\(v_i\)到\(v_j\)的有向路径,同时还有一条从\(v_j\)到\(v_i\)的有向路径,则称两个顶点强连通(\(strongly\ connected\)).如果有向图\(G\)的每两个顶点都强连通,称\(G\)是一个强连通图.有向图的极大强连通子图,称为强连通分量(\(strongly\ connected\ components\)). 万能的\(Tarjan\)算…
有向图的强连通分量即,在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 采用的算法是Kosaraju算法. 算法原理:对于图G,转置图(同图中的每边的方向相反)具有和原图完全一样的强连通分量. 具体实现: 1.对原图G进行深度优先遍历,记录每个节点的离开时间time[i]. 2…
题目链接 题意: 给定一张有向图.找出全部强连通分量,并输出. 思路:有向图的强连通分量用Tarjan算法,然后用map映射,便于输出,注意输出格式. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <map> #include <algorithm> using namespace std; const int MAXN = 2000; const in…
题目大意:       每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头 牛被所有的牛认为是受欢迎的.         先用tarjan求出每个强连通分量,再缩点,统计每个点的出度,如果有且只有1个出度为0的点,就输出这个点包含的节点数,否则输出0.   证明:       如果有强连通分量被孤立(即和其他强连通分量无边相连),那么…
一.dfs框架: vector<int>G[maxn]; //存图 int vis[maxn]; //节点访问标记 void dfs(int u) { vis[u] = ; PREVISIT(u); //访问节点u之前的操作 int d = G[u].size(); ; i < d; i++)//枚举每条边 { int v = G[u][i]; if(!vis[v])dfs(v); } POSTVISIT(u); //访问节点u之后的操作 } 二.无向图连通分量 void find_cc…
给一张有向图G, 求一个结点数最大的结点集,使得该结点集中任意两个结点u和v满足,要么u可以到达v, 要么v可以到达u(u和v相互可达也可以). 因为整张图可能存在环路,所以不好使用dp直接做,先采用有向图的强连通分量,进行缩点,然后得到一个有向无环图(DAG) 在采用记忆话dp 去做即可 #include <iostream> #include <cstdio> #include <algorithm> #include <string.h> #inclu…
一:tarjan算法详解 ◦思想: ◦ ◦做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间最早的节点的开始时间.(也就是之后的深搜所能到达的最小开始时间)初始时dfn[i]=low[i] ◦ ◦在DFS过程中会形成一搜索树.在搜索树上越先遍历到的节点,显然dfn的值就越小. ◦ ◦DFS过程中,碰到哪个节点,就将哪个节点入栈.栈中节点只有在其所属的强连通分量已经全部求出时,才会出栈. ◦…
好久没写博客了(都怪作业太多,绝对不是我玩的太嗨了) 所以今天要写的是一个高大上的东西:强连通 首先,是一些强连通相关的定义 //来自度娘 1.强连通图(Strongly Connected Graph)是指在有向图G中,如果对于每一对vi.vj,vi≠vj,从vi到vj和从vj到vi都存在路径,则称G是强连通图. 2.有向图的极大强连通子图,称为强连通分量(strongly connected components). 当然,看定义是肯定看不懂的,所以,我举个栗子说明一下 我们以下图为例,这是…
Tarjan算法 Tarjan算法是基于dfs算法,每一个强连通分量为搜索树中的一颗子树.搜索时,把当前搜索树中的未处理的结点加入一个栈中,回溯时可以判断栈顶到栈中的结点是不是在同一个强连通分量中.当dfn[u]=low[u]时,以u为根的搜索子树上的所有结点是一个强连通分量,其中dfn[]值表示结点的深度优先数,low[]值表示结点可以到达的优先数最小的祖先. Tarjan伪代码如下: Tarjan(u) { dfn[u] = low[u] = ++dep //dfn[]和low[]的初值 S…
https://www.byvoid.com/blog/scc-tarjan 主要思想 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量. 定义DFN(u)为节点u搜索的次序编号(时间戳),Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号.由定义可以得出, Low(u)=Min { DFN(u), Low(v),(u,v)为树枝边,u为v的父节点 DFN…
/* 题目大意:有N个cows, M个关系 a->b 表示 a认为b popular:如果还有b->c, 那么就会有a->c 问最终有多少个cows被其他所有cows认为是popular! 思路:强连通分量中每两个节点都是可达的! 通过分解得到最后一个连通分量A, 如果将所有的强连通分量看成一个大的节点,那么A一定是孩子节点(因为我们先 完成的是父亲节点的强连通分量)! 最后如果其他的强连通分量都可以指向A,那么 A中的每一个cow都会被其他cows所有的cows认为popular! *…
一.前人种树 博客:Kosaraju算法解析: 求解图的强连通分量…
d.看一个图是不是强连通图 s.求出强连通分量,看看有没有一个强连通分量包含所有点. c.Tarjan /* Tarjan算法 复杂度O(N+M) */ #include<iostream> #include<stdio.h> #include<string.h> using namespace std; ;//点数 ;//边数 struct Edge{ int to,next; }edge[MAXM]; int head[MAXN],tot; int Low[MAXN…
Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9073   Accepted: 3594 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a lis…
  [问题描述] 给定一个有向图,设计一个算法,求解并输出该图的各个强连通分量. package org.xiu68.exp.exp9; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class Exp9_2 { public static void main(String[] args) { int[][] graph=new int[][]{ {0,1,1,0,0}, {1,…
Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 53    Accepted Submission(s): 15 Problem Description Give a simple directed graph with N nodes and M edges. Please tell me the…
d.各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输, 问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件. 问题2:至少需要添加几条传输线路(边),使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件.s.首先找强连通分量,然后看强连通分量的入度为0点的总数,出度为0点的总数. 第一问为入度为0的强连通分量的个数. 第二问为入度为0的个数和出度为0的个数中大的.(将这个图的所有子树找出来,然后将一棵子树的叶子结…
在同一个DFS树中分离不同的强连通分量SCC; 考虑一个强连通分量C,设第一个被发现的点是 x,希望在 x 访问完时立刻输出 C,这样就可以实现 在同一个DFS树中分离不同的强连通分量了. 问题就转换为判断,一个点是否 是 第一个被发现的点,这样,可以利用之前的 点-双连通分离的数据结构, lowlink(u) 函数,为 u 及其后代能追溯到的最早祖先. 当 lowlink(u) == pre[u] (进树的时间),那么这个点 U 就是第一个被发现的点.那么这个 强连通分量就出来了. #incl…
题意:有n个命题,已知其中的m个推导,要证明n个命题全部等价(等价具有传递性),最少还需要做出几次推导. 思路:由已知的推导可以建一张无向图,则问题变成了最少需要增加几条边能使图变成强连通图.找出所有的强连通分量,将每一个连通分量视作一个大节点,则整张图变成了一张DAG.设出度为0的大节点个数为b,入度为0的大节点个数为a,则答案就是max(a,b). #include<iostream> #include<string> #include<algorithm> #in…