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

Posted 薰衣草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

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

uva 10792 无向图的边双连通分量

双连通分量(点-双连通分量&边-双连通分量)

Tarjan算法 双连通分量

DFS的运用(二分图判定无向图的割顶和桥,双连通分量,有向图的强连通分量)

无向图的割顶和桥,无向图的双连通分量入门详解及模板 -----「转载」

双连通分量 Road Construction POJ - 3352