关节点(atriculation point)算法
生活随笔
收集整理的這篇文章主要介紹了
关节点(atriculation point)算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
//求關節點(atriculation point)算法
/***某個頂點A時關節點必須滿足下列條件之一*1:A的是深度優先生成樹的根,并且A子樹的個數大于等于2。*2:A不是深度優先生成樹的根和葉子節點,并且A的子樹根以及子樹根的兒孫都沒有指向A祖先的回邊(回邊就是在圖中但不在生成樹中的邊)。*//**算法思想*1:在深度優先遍歷過程中,記錄下每棵頂點訪問的次序,在單純的dfs中visited[MAX]數組用來標記一個頂點是否被訪問過,但是在這里還用來記 錄訪問的次序,visited[i]>0表示此頂點已經被訪問過并且訪問的次序是visited[i]。2:當判斷A頂點是不是關節點的時候,需要知道需要知道A頂點的子樹以及子樹的兒孫時候有指向A頂點的祖先(即被訪問的次序小于A的頂點就是AA的祖先),A頂點的子樹及子樹的兒孫可能有許多的回邊指向A的祖先,我們需要求visted[A],low[w],visted[k]中最小的值就可以,這個最小的之就是A的low[A]值,low[MAX]數組用來記錄某個頂點(包括這個頂點)以及這個頂點的兒孫中指向這個頂點的祖先頂點中最小的次序頂點。但是怎么求low[MAX]中的值呢?low[v]=min{visited[v],low[w](w為v的鄰接點),visited[k](v到k的回邊)},其中visited[v]和visited[k]可以很容易求得,那low[w]怎么求呢?顯然這里是遞歸的概念,求low[v]需要知道他的所有的子樹根的low[w],同樣求low[w]需要知道w的所有子樹根的low[w'].當low[w] >= visited[v]v必定是關節點*///代碼參考
#include "stdio.h"
#include "string.h"
//圖的鄰接矩陣表示方法
int Matrix[8][8] = {/*a b c d e f g h*//*a*/{0,1,0,0,0,1,1,1},/*b*/{1,0,1,0,0,0,0,0},/*c*/{0,1,0,1,1,1,0,0},/*d*/{0,0,1,0,1,0,0,0},/*e*/{0,0,1,1,0,0,0,0},/*f*/{1,0,1,0,0,0,0,0},/*g*/{1,0,0,0,0,0,0,1},/*h*/{1,0,0,0,0,0,1,0},
};int count = 0;//當前有多少個頂點已經訪問過
int visited[10];//用來記錄頂點訪問的次序
int low[10];
int vertex_num = 8;
//v頂點的下一個鄰接點
int next_adjacent_vertex (int v,int index) {int i;for (i = index;i < 8;i++) {if (1 == Matrix[v][i]) {return i;}} return -1;//表示沒有下一個鄰接點了
}
void atriculation_point_step2 (int v) {int min;int w = -1;visited[v] = ++count;min = visited[v];while (-1 != (w = next_adjacent_vertex(v,w+1))) {if (0 == visited[w]) {atriculation_point_step2 (w);if (low[w] >= visited[v]) {printf ("-->%c\n",97+v);}if (min > low[w]) {min = low[w];}}else if(visited[w] < min){min = visited[w];//w已經被訪問過,w是v在生成樹上的祖先}}low[v] = min;
}void atriculation_point_step1 (int v) {int adjacent = next_adjacent_vertex (v,0); memset (visited,0,sizeof(visited));visited[v] = ++count;atriculation_point_step2(adjacent);if (count < vertex_num) {printf ("-->%c\n",97+v);while (-1!= (adjacent = next_adjacent_vertex(v,adjacent+1))) {if (0 == visited[adjacent]) {atriculation_point_step2(adjacent);}}}
}int main () { atriculation_point_step1 (0);printf ("%d\n",count);return 0;
}
總結
以上是生活随笔為你收集整理的关节点(atriculation point)算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拓扑排序--关键路径
- 下一篇: 网络最大流的三种基础算法