摘要:寻找强连通分支,利用构造深度搜索优先树的办法,找到有向图的强连通分支.
(1)基本思路:[1]首先利用深度搜索优先找到一颗深度搜索优先树.如果该树不包含所有的节点,那么对剩下的节点继续进行搜索.直到所有节点都被访问,这时候得到深度优先搜索树形成的森林.
[2]在搜索过程中对所有的节点进行编号(后序遍历).
[3]将该图进行反向,然后重新进行搜索,每次搜索的起点都找一个没有被访问的顶点中编号最低的点.
[4]第二次搜索中所获得的所有树就是强连通分支.
(2)算法分析:
[1]强连通分支应该是两次深度搜索优先树的交集,设点集合S同时存在于两次的深度优先搜索树A(根为x),B(根为y)中,那么对于点集中任何两点m,n,它们都是可以互相到达的.
[2]首先x可以到达A中的任何一点,那就意味着x->m,x->n.同时x在B中是根,因为每次搜索都是从编号最高的开始,x一定是该树中编号最高的(后序遍历),因此x就是y.那么对于B,x可以到达m,n.因为该树是反转图的生成树,那么在实际图中一定有,m->x,n->x;所以m,n可以通过x进行中转互相到达对方.
#include "stdafx.h"
#include "string.h"
#include "图论ADT.h"
static bool Isvisited[Number] = {false};
void Reverse (Graph G,Graph Gr)
{
int i = 0,v,w;
List L;
Initialize(Gr);
for(;i<=Number-1;i++)
{
L = G[i]->Next;
while(L!=NULL)
{
v = L->Element;
w = i;
Insert(Gr[v],w);
L = L->Next;
}
}
}
void FindForest(Graph G,int start,int &Numvisited,int & Index,int * Indexarray)
{
int v = G[start]->Element,w;
printf("%d ",v);
Isvisited[v] = true;
Numvisited ++;
List L = G[start]->Next;
while(L!=NULL)
{
w = L->Element;
if (Isvisited[w] == false )
{
FindForest(G,w,Numvisited,Index,Indexarray);
}
L = L->Next;
}
Indexarray[start] = Index++;
}
int FindNewNonvisited(bool *Isvisited)
{
int i = 0;
while(Isvisited[i] == true)
{
i++;
}
return i;
}
int Findnewvertex_highestIndex(bool* Isvisited,int * indexarray)
{
int i = -1,highest_index = 0,mark;
while(1)
{
while(Isvisited[++i] == true){}
if(i == 10)
break;
if (indexarray[i] >= highest_index)
{
highest_index = indexarray[i];
mark = i;
}
}
return mark;
}
void Findstrongconnect_drive(Graph G,int start)
{
int Numvisited = 0;
int Index = 0;
int Indexarray[Number];
Graph Gr;
while(Numvisited < Number)
{
FindForest(G,start,Numvisited,Index,Indexarray);
start = FindNewNonvisited(Isvisited);
}
Reverse(G,Gr);
Numvisited = 0;
memset(Isvisited,0,sizeof(Isvisited));
while(Numvisited < Number)
{
puts("\n");
start = Findnewvertex_highestIndex(Isvisited,Indexarray);
FindForest(Gr,start,Numvisited,Index,Indexarray);
}
}
主函数:
int _tmain(int argc, _TCHAR* argv[])
{
Graph G,Gr;
Initialize(G);
Insert(G[0],1);
Insert(G[0],3);
Insert(G[1],2);
Insert(G[1],5);
Insert(G[2],0);
Insert(G[2],3);
Insert(G[2],4);
Insert(G[3],4);
Insert(G[5],2);
Insert(G[6],5);
Insert(G[6],7);
Insert(G[7],5);
Insert(G[7],9);
Insert(G[8],7);
Insert(G[9],8);
Reverse(G,Gr);
int Indexarray[Number];
int start = 1 ,Index = 0 ,Numvisited = 0;
Findstrongconnect_drive(G,1);
return 0;
}