Expm 9_2 有向图的强连通分量问题

Posted 薰衣草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Expm 9_2 有向图的强连通分量问题相关的知识,希望对你有一定的参考价值。

 

【问题描述】

给定一个有向图,设计一个算法,求解并输出该图的各个强连通分量。

 

技术分享图片
  1 package org.xiu68.exp.exp9;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 import java.util.Stack;
  6 
  7 public class Exp9_2 {
  8     public static void main(String[] args) {
  9         int[][] graph=new int[][]{
 10             {0,1,1,0,0},
 11             {1,0,0,0,0},
 12             {0,0,0,1,0},
 13             {0,0,0,0,1},
 14             {0,0,1,0,0}
 15         };
 16         MGraph m1=new MGraph(graph, 5);
 17         m1.getSccs();
 18     }
 19 }
 20 
 21 class MGraph{
 22     private int[][] graph;        //有向图
 23     private int[][] rGraph;        //有向图的反向图
 24     private int vexNum;            //顶点数量
 25     Stack<Integer> stack;        //存储反向图深度优先遍历的post值,从大到小排序
 26     
 27     public MGraph(int[][] graph,int vertexNum){
 28         this.graph=graph;
 29         this.vexNum=vertexNum;
 30         stack=new Stack<>();
 31         rGraph=new int[vexNum][vexNum];    //反向图
 32         
 33         //求原图的反向图
 34         for(int i=0;i<vexNum;i++){
 35             for(int j=i+1;j<vexNum;j++){
 36                 rGraph[i][j]=graph[j][i];
 37                 rGraph[j][i]=graph[i][j];
 38             }
 39         }
 40     }
 41     
 42     
 43     public void getSccs(){
 44         rDFSTraverse();    //先对反向图进行深度优先遍历
 45         
 46         boolean[] visited=new boolean[vexNum];    //记录深度优先遍历原图过程中已经访问的顶点
 47         
 48         List<List<Integer>> sccs=new ArrayList<>();    //存放每一个强连通部件对应的顶点
 49         int n=0;                                    //第几个强连通部件
 50         while(!stack.isEmpty()){
 51             int v=stack.pop();
 52             if(!visited[v]){
 53                 sccs.add(new ArrayList<Integer>());
 54                 DFS(visited,v,sccs,n);
 55                 n++;
 56             }
 57         }
 58         //打印强连通部件
 59         for(int i=0;i<sccs.size();i++){
 60             System.out.print("第"+i+"个强连通部件:");
 61             for(int j=0;j<sccs.get(i).size();j++){
 62                 System.out.print(sccs.get(i).get(j)+" ");
 63             }
 64             System.out.println();
 65         }
 66     }
 67     /*
 68      * 对原图进行深度优先遍历
 69      * 在汇点强连通部件中对某个顶点进行深度优先遍历则刚好访问该强连通部件的所有顶点
 70      */
 71     private void DFS(boolean[] visited,int v,List<List<Integer>> sccs,int n){
 72         sccs.get(n).add(v);
 73         visited[v]=true;
 74         for(int i=0;i<vexNum;i++){
 75             if(graph[v][i]==1 && !visited[i])
 76                 DFS(visited,i,sccs,n);
 77         }
 78     }
 79     
 80 //**************************************************************    
 81     /*
 82      * 对反向图进行深度优先遍历,post值最大的顶点将位于反向图中的一个源点强连通部件,
 83      * 也就是原图中的某个汇点连通部件的某个顶点
 84      * 求得各个顶点的post值,压入栈中
 85      */
 86     public void rDFSTraverse(){
 87         boolean[] visited=new boolean[vexNum];
 88         for(int i=0;i<vexNum;i++){
 89             if(!visited[i]){
 90                 rDFS(visited,stack,i);
 91             }
 92         }
 93     }
 94     //对反向图做深度优先遍历
 95     private void rDFS(boolean[] visited,Stack<Integer> stack,int v){
 96         visited[v]=true;
 97         for(int i=0;i<vexNum;i++){
 98             if(rGraph[v][i]==1 && !visited[i]){
 99                 rDFS(visited,stack,i);
100             }
101         }
102         stack.push(v);
103     }
104 }
View Code

 

以上是关于Expm 9_2 有向图的强连通分量问题的主要内容,如果未能解决你的问题,请参考以下文章

图论有向图的强连通分量

图论有向图的强连通分量

图论有向图的强连通分量

图论有向图的强连通分量

求有向图的强连通分量个数 之 Kosaraju算法

无向图的强连通分量