• 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
  • 相关阅读:
    利用libxml2解析xml文档
    找出两个链表的第一个公共结点
    [转载]风雨20年:我所积累的20条编程经验
    inotify监测文件及文件夹
    [转载]linux下svn常用指令
    利用zlib进行数据压缩
    2013腾讯编程马拉松初赛:郑厂长系列故事——体检
    Socket编程之简单介绍
    C语言中static的作用总结
    写程序实现wireshark的抓包功能
  • 原文地址:https://www.cnblogs.com/xiu68/p/7988590.html
Copyright © 2020-2023  润新知