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算法的更多相关文章

  1. 算法笔记_144:有向图强连通分量的Tarjan算法(Java)

    目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连 ...

  2. 有向图强连通分量的Tarjan算法

    有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...

  3. 【转】有向图强连通分量的Tarjan算法

    原文地址:https://www.byvoid.com/blog/scc-tarjan/ [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly con ...

  4. 【转载】有向图强连通分量的Tarjan算法

    转载地址:https://www.byvoid.com/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly conn ...

  5. 有向图强连通分量的Tarjan算法(转)

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  6. 『图论』有向图强连通分量的Tarjan算法

    在图论中,一个有向图被成为是强连通的(strongly connected)当且仅当每一对不相同结点u和v间既存在从u到v的路径也存在从v到u的路径.有向图的极大强连通子图(这里指点数极大)被称为强连 ...

  7. 有向图强连通分量的Tarjan算法及模板

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强联通(strongly connected),如果有向图G的每两个顶点都强联通,称有向图G是一个强联通图.非强联通图有向 ...

  8. 强连通分量的Tarjan算法

    资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...

  9. 有向图强连通分量的Tarjan算法和Kosaraju算法

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

随机推荐

  1. javascript实现checkbox提交submit请求

    javascript实现checkbox提交submit请求 背景:使用django模板中for来形成多个checkbox,需要点击单个checkbox并查询数据触发submit请求到后台,djang ...

  2. PHP EOF使用说明

    PHP EOF(heredoc) 使用说明 PHP EOF(heredoc)是一种在命令行shell(如sh.csh.ksh.bash.PowerShell和zsh)和程序语言(像Perl.PHP.P ...

  3. 浅谈HTTP和HTTPS

    HTTP和HTTPS协议 网络协议:计算机之间为了实现网络通信而达成的一种“约定”或“规则”,有了这种“约定”,不同厂商的生产设备,以及不同不同操作系统组成的计算机之间,就可以实现通信. HTTP(H ...

  4. MyBatis入门知识汇总

     为什么要使用MyBatis? 我们都知道,在学习mybatis之前,要在Java中操作数据库,需要用到JDBC,但是在使用JDBC时会有许多缺陷. 比如: 1.使用时需要先进行数据库连接,不用后要立 ...

  5. Java openrasp学习记录(一)

    前言: 最近一直在做学校实验室安排的项目,太惨了,没多少时间学习新知识,不过rasp还是要挤挤时间学的,先从小例子的分析开始,了解rasp的基本设计思路,后面详细阅读openrasp的源码进行学习!欢 ...

  6. php-fpm搜索php.ini很奇怪的一个现象

    php-fpm 找不到 php.ini phpinfo 或者 php -i 上来看,搜索的目录都是/usr/local/php/etc下,但是事实上并没用去找这个目录 bin/php --ini 来看 ...

  7. 02.drf不使用serializers返回数据

    drf 可以使用不经过model和serialzier的数据返回,也可以配置权限 class DashboardStatusViewset(viewsets.ViewSet): "" ...

  8. 使用Html5对图片加水印及多图合成

                                                                             转载请注明原地址:                   ...

  9. ORM多表增删改查

    一 创建多表 在models.py里创建4张表:Author(作者).AuthorDetail(作者详细信息).Publish(出版社).Book(书) 四张表关系为: (1)首先创建一对一关系.On ...

  10. poj3694 连通无向图图加边后有多少桥

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10261   Accepted: 3807 Descript ...