無方向連通図の関節点を解く


参考データ構造(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)はエッジバックである}}
実装コードは以下の通りです:(テストコードが少ないため、プログラムがエラーになる可能性が高いので、エラーを発見した友达がタイムリーに指摘してほしい)
#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)            ,         ,    。