• Expm 9_3 无向图的双连通分量问题


     

    【问题描述】

    给定一个无向图,设计一个算法,判断该图中是否存在关节点,并划分双连通分量。

      1 package org.xiu68.exp.exp9;
      2 
      3 import java.util.Stack;
      4 
      5 public class Exp9_3 {
      6     
      7     //无向图的双连通分量问题
      8     public static void main(String[] args) {
      9         // TODO Auto-generated method stub
     10         int[][] graph=new int[][]{
     11             {0,1,1,0,0},
     12             {1,0,1,0,0},
     13             {1,1,0,1,1},
     14             {0,0,1,0,1},
     15             {0,0,1,1,0}
     16         };
     17         MGraph1 m=new MGraph1(graph);
     18         m.bicompDFS(0);
     19         //运行结果
     20             /*
     21              双连通部件: 
     22             (4,2) (3,4) (2,3) 
     23             双连通部件: 
     24             (2,0) (1,2) (0,1)
     25              */
     26     }
     27 
     28 }
     29 
     30 
     31 //邻接矩阵表示无向图
     32 class MGraph1{
     33     private int vexNum;                //顶点数量
     34     private int[][] edges;            //
     35     
     36     private Stack<Edge> edgeStack;    //边栈
     37     private int[][] visitedEdge;    //记录哪条边已经访问过,1为访问过,0为未访问过
     38     
     39     private int[] color;            //记录顶点的访问状态,-1为未访问到,0为正在搜索中,1为已搜索完成
     40     private int    clock;                //访问时刻
     41     private int[] pre;                //记录顶点的访问时间
     42     private int[] post;                //记录顶点的结束访问时刻
     43 
     44     
     45     public MGraph1(int[][] edges) {
     46         this.edges = edges;
     47         this.vexNum=edges.length;
     48         this.color=new int[vexNum];
     49         this.pre=new int[vexNum];
     50         this.post=new int[vexNum];
     51         this.clock=1;
     52         this.edgeStack=new Stack<>();
     53         this.visitedEdge=new int[vexNum][vexNum];
     54         
     55         //初始化所有结点为未访问状态
     56         for(int i=0;i<vexNum;i++){
     57             color[i]=-1;
     58         }
     59     }
     60     
     61     //返回从v出发,经过一条其后代组成的边包括回退边,所能访问到的顶点的最小的pre值
     62     public int bicompDFS(int v){
     63         //color[v]的值:-1为未访问到,0为正在搜索中,1为已搜索完成
     64         color[v]=0;                        //顶点v正在搜索中
     65         pre[v]=clock;                    //顶点v的访问时刻
     66         clock++;
     67         
     68         int back=pre[v];    //表示从v出发,经过一条其后代组成的边包括回退边,所能访问到的顶点的最小的pre值
     69         
     70         for(int i=0;i<vexNum;i++){
     71             if(edges[v][i]==1 && color[i]!=1 && visitedEdge[v][i]!=1){    //顶点v和i之间有边未访问过
     72                 
     73                 edgeStack.push(new Edge(v,i));            //放入边栈中
     74                 visitedEdge[v][i]=visitedEdge[i][v]=1;    //记录边已访问过
     75                 
     76                 if(color[i]==-1){                 //树边
     77                     int wBack=bicompDFS(i);
     78                     
     79                     if(wBack>=pre[v]){          //说明v的子树没有回路关联到v的祖先
     80                         System.out.println("双连通部件: ");
     81                         Edge e=edgeStack.pop();
     82                         while(true){
     83                             System.out.print("("+e.getHead()+","+e.getTail()+") ");
     84                             if(e.getHead()==v && e.getTail()==i)
     85                                 break;
     86                             e=edgeStack.pop();
     87                         }
     88                         System.out.println();
     89                     }
     90                     if(wBack<back)
     91                         back=wBack;                //记录从v开始经过的顶点的最小的pre值
     92                 }else if(color[i]==0){            //回边
     93                     if(pre[i]<back)
     94                         back=pre[i];            //记录从v开始经过的顶点的最小的pre值
     95                 }
     96             }//if
     97         }//for
     98         
     99         post[v]=clock;
    100         clock++;
    101         color[v]=1;
    102         
    103         return back;
    104     }
    105 }
    106 
    107 class Edge{
    108     private int head;    //边的头
    109     private int tail;    //边的尾
    110     
    111     public Edge(int head,int tail){
    112         this.head=head;
    113         this.tail=tail;
    114     }
    115 
    116     public int getHead() {
    117         return head;
    118     }
    119 
    120     public void setHead(int head) {
    121         this.head = head;
    122     }
    123 
    124     public int getTail() {
    125         return tail;
    126     }
    127 
    128     public void setTail(int tail) {
    129         this.tail = tail;
    130     }
    131     
    132 }
    View Code
  • 相关阅读:
    安装好php后找不到php.ini
    Nginx 和 PHP 的两种部署方式比较
    高性能Web服务之lnmp架构应用
    >/dev/null 2>&1的含义
    LC_ALL=C的含义
    深入理解PHP Opcode缓存原理
    iostat 监视I/O子系统
    sar 找出系统瓶颈的利器
    Linux常用命令汇总
    linux增加自定义path和manpath
  • 原文地址:https://www.cnblogs.com/xiu68/p/7988600.html
Copyright © 2020-2023  润新知