博客
关于我
【alg4-有向图】Kosaraju算法(计算强连通分量)
阅读量:684 次
发布时间:2019-03-17

本文共 2284 字,大约阅读时间需要 7 分钟。

有向图中的强连通性是图论中一个重要的概念,它描述了两个顶点之间的相互可达性。两个顶点v和w被称为强连通的,当且仅当它们互为可达,也就是在有向图中既存在一条从v指向w的路径,也存在一条从w指向v的路径。强连通性具有自反性、对称性和传递性,这些性质使其成为一种等价关系。基于这种等价关系,有向图可以划分为多个强连通分量,每个强连通分量是最大的由相互强连通的顶点组成的子集。

强连通分量的划分与无向图中的连通性类似,但有向图中的连通性要求双向的可达性。一个有向图可能包含1到V个强连通分量,其中V是图中的顶点总数。一个强连通图(即每个顶点都可以从任何其他顶点到达)只包含一个强连通分量,而一个有向无环图(DAG)则包含每个顶点一个强连通分量。

Kosaraju算法是一种有效地找出有向图中的强连通分量的资源敏感算法。其核心思想是通过两次深度优先搜索(DFS)来确定强连通分量。第一次DFS运行在原图的反向图上,生成一个顶点的逆后序序列。第二次DFS在原图上按照这个逆后序序列进行处理,每次递归调用处理的顶点都属于同一个强连通分量。

Kosaraju算法的关键性质是其构造函数中的每一次递归调用所标记的顶点都在同一强连通分量中。这一点由该算法的命题所证实,这使得Kosaraju算法成为强连通性分析的经典方法之一。

以下是一个实现Kosaraju算法的Java代码示例:

package section4_2;public class KosarajuSCC {    private boolean[] marked;    private int[] id;    private int count;    public KosarajuSCC(Digraph G) {        marked = new boolean[G.V()];        id = new int[G.V()];        DepthFirstOrder order = new DepthFirstOrder(G.reverse());        for (int s : order.reversePost()) {            if (!marked[s]) {                dfs(G, s);                count++;            }        }    }    private void dfs(Digraph G, int v) {        marked[v] = true;        id[v] = count;        for (int w : G.adj(v)) {            if (!marked[w]) {                dfs(G, w);            }        }    }    public boolean stronglyConnected(int v, int w) {        return id[v] == id[w];    }    public int id(int v) {        return id[v];    }    public int count() {        return count;    }    public static void main(String[] args) {        int[][] data = {            {4, 2},            {2, 3},            {3, 2},            {6, 0},            {0, 1},            {2, 0},            {11, 12},            {12, 9},            {9, 10},            {9, 11},            {8, 9},            {10, 12},            {11, 4},            {4, 3},            {3, 5},            {7, 8},            {8, 7},            {5, 4},            {0, 5},            {6, 4},            {6, 9},            {7, 6}        };        int vn = 13;        int en = 22;        Digraph digraph = new Digraph(vn, en, data);        KosarajuSCC scc = new KosarajuSCC(digraph);        System.out.println(scc.count());        System.out.println(scc.id(1));        System.out.println(scc.id(2));        System.out.println(scc.id(9));        System.out.println(scc.id(6));        System.out.println(scc.id(8));    }}

转载地址:http://aichz.baihongyu.com/

你可能感兴趣的文章
oracle 课堂笔记
查看>>
Oracle 返回结果集的 存储过程
查看>>
Oracle 递归
查看>>
Oracle 递归函数与拼接
查看>>
oracle 逻辑优化,提升高度,综合SQL上下文进行逻辑优化
查看>>
oracle 闪回关闭,关闭闪回即disable flashback的操作步骤
查看>>
oracle 限制用户并行,insert /*parallel */ 到不同用户,并行起不来的问题
查看>>
oracle--用户,权限,角色的管理
查看>>
Oracle-定时任务-JOB
查看>>
oracle.dataaccess 连接池,asp.net使用Oracle.DataAccess.dll连接Oracle
查看>>
oracle00205报错,Oracle控制文件损坏报错场景
查看>>
Oracle10g EM乱码之快速解决
查看>>
Oracle10g下载地址--多平台下的32位和64位
查看>>
Oracle10g安装了11g的ODAC后,PL/SQL连接提示TNS:无法解析指定的连接标识符
查看>>
oracle11g dataguard物理备库搭建(关闭主库cp数据文件到备库)
查看>>
Oracle11G基本操作
查看>>
Oracle11g服务详细介绍及哪些服务是必须开启的?
查看>>
Oracle11g静默安装dbca,netca报错处理--直接跟换操作系统
查看>>
oracle12安装软件后安装数据库,然后需要自己配置监听
查看>>
Oracle——08PL/SQL简介,基本程序结构和语句
查看>>