無方向連通図の関節点を解く
参考データ構造(C言語版)第七章、アルゴリズム7.10と7.11
構想を解く.
1.深さ優先生成木の根は関節点の必須条件であり、少なくとも2人の子供がいる
2.他の頂点uが関節点である要件は、少なくとも1人の子供wを有することであり、w,wの子孫および1つのエッジからなる経路を経てuの祖先に到達することは不可能である.頂点uおよびその関連するエッジを削除すると、wおよびその子孫がuの祖先と連絡を切るからである.
頂点wの祖先がw自体を含むと仮定し、1つの頂点がその子孫および1つのエッジを通って到達できる最高祖先を表すために、図の各頂点wについて、low(w)は、wからその子孫および1つのエッジを通って到達できる最高祖先のdfn(ある頂点が深さ優先ループでアクセスされる順序を示す)と定義される.
明らかにlow(w)は、wがその子孫および1つのエッジを通って到達できる頂点のdfnの中で最も低く、次の式によって計算することができる.
low(w)=min{dfn(w),min{low(x)|xはwの一人の子である},min{dfn(x)|(w,x)はエッジバックである}}
実装コードは以下の通りです:(テストコードが少ないため、プログラムがエラーになる可能性が高いので、エラーを発見した友达がタイムリーに指摘してほしい)
構想を解く.
1.深さ優先生成木の根は関節点の必須条件であり、少なくとも2人の子供がいる
2.他の頂点uが関節点である要件は、少なくとも1人の子供wを有することであり、w,wの子孫および1つのエッジからなる経路を経てuの祖先に到達することは不可能である.頂点uおよびその関連するエッジを削除すると、wおよびその子孫がuの祖先と連絡を切るからである.
頂点wの祖先がw自体を含むと仮定し、1つの頂点がその子孫および1つのエッジを通って到達できる最高祖先を表すために、図の各頂点wについて、low(w)は、wからその子孫および1つのエッジを通って到達できる最高祖先のdfn(ある頂点が深さ優先ループでアクセスされる順序を示す)と定義される.
明らかにlow(w)は、wがその子孫および1つのエッジを通って到達できる頂点のdfnの中で最も低く、次の式によって計算することができる.
low(w)=min{dfn(w),min{low(x)|xはwの一人の子である},min{dfn(x)|(w,x)はエッジバックである}}
実装コードは以下の通りです:(テストコードが少ないため、プログラムがエラーになる可能性が高いので、エラーを発見した友达がタイムリーに指摘してほしい)
#include <cstdio>
#include <cstdlib>
#define VERTEX_NUM 7
#define NOT_VISITED 0
int dfn;//
void find_articulation(int adj[][VERTEX_NUM], int visit[], int low[]);// ,
void DFS_articulation(int adj[][VERTEX_NUM], int vertex, int visit[], int low[]);// vertex ,
int main()
{
// ,-1
int Adj[VERTEX_NUM][VERTEX_NUM] = {
{0, 1, 3, -1},
{1, 0, 2, 3, 4, -1},
{2, 1, 3, 4, 5, -1},
{3, 0, 1, 2, 4, -1},
{4, 1, 2, 3, 5, -1},
{5, 4, 6, -1},
{6, 5, -1}
};
int low[VERTEX_NUM];//low[]
int visit[VERTEX_NUM];
for (int i = 0; i < VERTEX_NUM; i++)
visit[VERTEX_NUM] = NOT_VISITED;
// ,
find_articulation(Adj, visit, low);
system("pause");
return 0;
}
void find_articulation(int adj[][VERTEX_NUM], int visit[], int low[]) //visit[i] i
{
dfn = 1;
visit[adj[0][0]] = 1;// adj[0][0]
for (int i = 1; i < VERTEX_NUM; i++)
visit[i] = NOT_VISITED;
int vertex = adj[0][1];
DFS_articulation(adj, vertex, visit, low);
if (dfn < VERTEX_NUM) //
{
printf("%d ", vertex);//
for (int j = 1; adj[0][j] != -1; j++)
if (visit[adj[0][j]] == NOT_VISITED)
DFS_articulation(adj, adj[0][j], visit, low);
}
}
void DFS_articulation(int adj[][VERTEX_NUM], int vertex, int visit[], int low[])
{
dfn++;
int min = dfn;
visit[vertex] = dfn;
for (int j = 1; adj[vertex][j] != -1; j++)
{
int w = adj[vertex][j];
if (visit[w] == NOT_VISITED)
{
DFS_articulation(adj, w, visit, low);
if (low[w] < min)
min = low[w];
if (low[w] >= visit[vertex])
printf("%d ", vertex);//
}
else if (visit[w] < min)
min = visit[w];//w ,w vertex
}
low[vertex] = min;
}
// :Stack around the variable 'visit' was corrupted
//
// “project-> ->c/c++-> -> , 。
// MSDN 。 RTC1 。 ,
// , 。 。
// , , , 。
// VS2005(2008) , , 。