Java实现有向图强连通分量的Tarjan算法
1 问题描述
引用自百度百科:
如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。
Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。
定义DFN(u)为节点u搜索的次序编号(时间戳),Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号。
当DFN(u)=Low(u)时,以u为根的搜索子树上所有节点是一个强连通分量。
2 解决方案
下面代码所使用图:

package com.liuzhen.practice;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static int MAX = 100;
public static int count; //用于对图中顶点遍历的次序进行计数
public static int n;
public static int[] DFN = new int[MAX]; //记录图中每个节点的DFS遍历的时间戳(即次序)
public static int[] Low = new int[MAX]; //记录每个顶点的所在树的根节点编号
public static boolean[] inStack = new boolean[MAX]; //用于记录当前节点是否在栈中
public static Stack<Integer> stack;
public void init(int n) {
count = 0;
stack = new Stack<Integer>();
for(int i = 0;i <= n;i++) {
DFN[i] = -1; //代表顶点i未被遍历
Low[i] = -1;
inStack[i] = false;
}
}
static class edge {
public int a; //边的起点
public int b; //边的终点
edge(int a, int b) {
this.a = a;
this.b = b;
}
}
public void dfs(ArrayList<edge>[] map, int start) {
DFN[start] = count++;
Low[start] = DFN[start];
stack.push(start);
inStack[start] = true;
int j = start;
for(int i = 0;i < map[start].size();i++) {
j = map[start].get(i).b;
if(DFN[j] == -1) { //顶点j未被遍历
dfs(map, j);
Low[start] = Math.min(Low[start], Low[j]);
} else if(inStack[j]) {
Low[start] = Math.min(Low[start], DFN[j]);
}
}
if(DFN[start] == Low[start]) {
System.out.print("强连通分量:");
do {
j = stack.pop();
System.out.print(j+" ");
inStack[j] = false;
} while(start != j);
System.out.println();
}
return;
}
public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
n = in.nextInt();
test.init(n);
int k = in.nextInt(); //有向图的边数目
@SuppressWarnings("unchecked")
ArrayList<edge>[] map = new ArrayList[n + 1];
for(int i = 0;i <= n;i++)
map[i] = new ArrayList<edge>();
in.nextLine();
for(int i = 0;i < k;i++) {
int a = in.nextInt();
int b = in.nextInt();
map[a].add(new edge(a, b));
}
test.dfs(map, 1);
}
}
运行结果:
8
2
3
4
4
5
1
6
6
强连通分量:6
强连通分量:5
强连通分量:3 4 2 1
Java实现有向图强连通分量的Tarjan算法的更多相关文章
- 算法笔记_144:有向图强连通分量的Tarjan算法(Java)
目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连 ...
- 有向图强连通分量的Tarjan算法
有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...
- 【转】有向图强连通分量的Tarjan算法
原文地址:https://www.byvoid.com/blog/scc-tarjan/ [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...
- 【转载】有向图强连通分量的Tarjan算法
转载地址:https://www.byvoid.com/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly conn ...
- 有向图强连通分量的Tarjan算法(转)
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
- 『图论』有向图强连通分量的Tarjan算法
在图论中,一个有向图被成为是强连通的(strongly connected)当且仅当每一对不相同结点u和v间既存在从u到v的路径也存在从v到u的路径.有向图的极大强连通子图(这里指点数极大)被称为强连 ...
- 有向图强连通分量的Tarjan算法及模板
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强联通(strongly connected),如果有向图G的每两个顶点都强联通,称有向图G是一个强联通图.非强联通图有向 ...
- 强连通分量的Tarjan算法
资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...
- 有向图强连通分量的Tarjan算法和Kosaraju算法
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
随机推荐
- PHP带标签的字符串去除标签,计算字符串长度的两种格式,截取字符串
$str = "<p>看地方撒地方<i>fdsafsdfsd</i><img src="/static/img/fdsf.jpg" ...
- JS中各种变量类型在条件判断为false的情况
var a = undefined; ->false var a = 0; ->false var a = 0.0; ->false var a = NaN; ->false ...
- unittest详解 跳过用例的执行(skip)
在执行测试用例时,有时候有些用例是不需要执行的,那我们怎么办呢?难道删除这些用例?那下次执行时如果又需要执行这些用例时,又把它补回来?这样操作就太麻烦了. unittest提供了一些跳过指定用例的方法 ...
- CSS像素与绝对像素
之前在电视的webview上投放广告页面时,遇到了个问题,就是视窗大小和文档大小不一致.最后发现原来有CSS Pixel这个概念,搜集了一些资料,希望能把这个问题捋捋清楚. 首先提出一个大家常常会忽略 ...
- css3复杂选择器
一.复杂选择器 1.兄弟选择器 兄弟元素,具备相同父元素的平级元素之间称为兄弟元素 兄弟选择器,只能找弟弟,不能找哥哥,只能往后找,不能往前找 ①相邻兄弟选择器 选择器 + 选择器{} 获取紧紧挨在某 ...
- 2.2 Go变量类型
内置类型 值类型: bool 布尔类型 int(32 or 64), int8, int16, int32, int64 整数类型 uint(32 or 64), uint8(byte), uint1 ...
- PG 更新统计信息
http://blog.chinaunix.net/uid-24774106-id-3802225.html 一.vacuum的效果: 1.1释放,再利用 更新/删除的行所占据的磁盘空间. 第一点的原 ...
- 四、HTML属性—— HTML 元素提供的附加信息
HTML属性 (1)属性一般描述于开始标签 (2)属性总是以名称/值对的形式出现,比如:name="value" (3)使用小写属性 HTML属性值 应该始终被包括在引号内. —— ...
- python+selenium实现百度关键词搜索自动化操作
缘起 之前公司找外面网络公司做某些业务相关关键词排名,了解了一下相关的情况,网络公司只需要我们提供网站地址和需要做的关键词即可,故猜想他们采取的方式应该是通过模拟用户搜索提升网站权重进而提升排名. 不 ...
- js中时间戳和时间格式之间的转换
//时间格式转化 getNowDate(timestamp) { var date = new Date(timestamp); //时间戳为10位需*1000,时间戳为13位的话不需乘1000 va ...