目录

1 问题描述

2 解决方案


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);
}
}

运行结果:

6
8
1 2
1 3
2 4
3 4
3 5
4 1
4 6
5 6
强连通分量:6
强连通分量:5
强连通分量:3 4 2 1

参考资料:

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

算法笔记_144:有向图强连通分量的Tarjan算法(Java)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. Java实现有向图强连通分量的Tarjan算法

    1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为 ...

  8. 强连通分量的Tarjan算法

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

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

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

随机推荐

  1. PHP 笔记——String 字符串

    1. 定义 单引号括起来的字符串被原样输出. 双引号字符串中的变量被PHP解析为变量值. 2. 获取字符串长度 strlen(string $string): int 在utf-8下,汉字占3个字符, ...

  2. [BZOJ4289][PA2012]TAX(最短路)

    首先考虑一种暴力做法,为每条边拆成两条有向边,各建一个点.若某两条边有公共点,则在边所对应的点之间连一条边,权值为两条边中的较大值.这样跑最短路是$O(m^2\log m)$的. 用类似网络流中补流的 ...

  3. HDU 5514 Frogs(容斥原理)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5514 [题目大意] m个石子围成一圈,标号为0~m-1,现在有n只青蛙,每只每次跳a[i]个石子, ...

  4. 【二分查找-最大化平均值】POJ2976 - Dropping Test

    [题目大意] 给出n组ai和bi,去掉k个使得a的总和除以b的总和最大. [思路] 也就是取(n-k)个数,最大化平均值,见<挑战程序设计竞赛>P144,最后公式为c(x)=((ai-x* ...

  5. BZOJ 1040 ZJOI 2008 骑士 树形DP

    题意: 有一些战士,他们有战斗力和讨厌的人,选择一些战士,使他们互不讨厌,且战斗力最大,范围1e6 分析: 把战士看作点,讨厌的关系看作一条边,连出来的是一个基环树森林. 对于一棵基环树,我们找出环, ...

  6. CentOS包管理yum常用命令(转)

    一.安装 yum install 全部安装yum install package1 安装指定的安装包package1yum groupinsall group1 安装程序组group1 二.更新和升级 ...

  7. 典型案例收集-使用OpenVPN连通多个机房内网(转)(静态路由)

    说明: 1.这篇文章主要是使用静态路由表实现的多个机房通过VPN连接后的子网机房互通. 2.OpenVPN使用的是桥接模式(server-bridge和dev tap),这个是关键点,只有这样设置才可 ...

  8. <摘录>linux signal 列表

    Linux 信号表   Linux支持POSIX标准信号和实时信号.下面给出Linux Signal的简表,详细细节可以查看man 7 signal. 默认动作的含义如下: 中止进程(Term) 忽略 ...

  9. 终于理解了什么是LGPL

    GPL 我 们很熟悉的Linux就是采用了GPL.GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样.GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费 ...

  10. WPF支持GIF的各种方法

    2012.12.18更新:修复下载链接 已知WPF的Image元素只能显示GIF图片的第一帧,而MediaElement不能加载作为资源或内嵌的资源的GIF图片,所以网上有几种实现方法. 我抄袭网上提 ...