• 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
  • 相关阅读:
    python 数据分析3
    python 数据分析2
    Python 数据分析1
    Python18 Django 基础
    Python 17 web框架&Django
    一只救助犬的最后遗言
    With As 获取 id parentId 递归获取所有
    分布式事物
    div 浮动框
    sql时间比较
  • 原文地址:https://www.cnblogs.com/xiu68/p/7988590.html
Copyright © 2020-2023  润新知