//头文件
#include <vector>
#include <map>
#include <utility>
#include <cassert>
#include <iostream>
#include <cmath>
using namespace std;
namespace dfst
{
const static int INVALID_VERTEX = -1;
typedef struct _Node
{
int v;
int v_parent;
bool invested;
_Node( int _v=INVALID_VERTEX, int _v_parent=INVALID_VERTEX, bool _invested=false )
:v(_v), v_parent(_v_parent), invested(_invested)
{}
}Node, *pNode;
vector<vector<int> > vGraph;
vector<Node> vDFSTree;
int iTreeSize;
void InitTree(void)
{
iTreeSize = vGraph.size();
vDFSTree.clear();
vDFSTree.resize( iTreeSize );
}
void dfs(int src)
{
vDFSTree[src].invested = true;
vDFSTree[src].v = src;
for ( vector<int >::iterator it=vGraph[src].begin(); it!=vGraph[src].end(); ++it )
{
if ( !vDFSTree[*it].invested )
{
cout << *it <<" ";
vDFSTree[*it].v_parent = src;
dfs( *it );
}
}
}
void PrintGraph(void)
{
int i(0);
for ( vector<vector<int> >::iterator itvv=vGraph.begin(); itvv!=vGraph.end(); ++itvv )
{
cout << i++ << ": ";
for ( vector<int >::iterator itv=itvv->begin(); itv!=itvv->end(); ++itv )
cout << *itv << " ";
cout << endl;
}
}
void PrintDFSTree(void)
{
for ( int i=0; i<iTreeSize; ++i )
cout << vDFSTree[i].v_parent << "-->" << vDFSTree[i].v << endl;
}
void PrintAll(void)
{
cout << "depth-first spanning tree:" << endl;
PrintGraph();
PrintDFSTree();
}
};
namespace dfst_ex
{
const static int INVALID_VERTEX = -1;
const static int INVALID_VALUE = -1;
typedef struct _Node
{
int v;
int v_parent;
int num;
int low;
bool invested;
_Node( int _v=INVALID_VERTEX, int _v_parent=INVALID_VERTEX,
int _num=INVALID_VALUE, int _low=INVALID_VALUE, bool _invested=false )
:v(_v), v_parent(_v_parent), num(_num), low(_low), invested(_invested)
{}
}Node, *pNode;
vector<vector<int> > vGraph;
vector<Node> vDFSTree;
map<int, int > mArticulationPoint;
int iTreeSize;
void InitTree(void)
{
iTreeSize = vGraph.size();
vDFSTree.clear();
vDFSTree.resize( iTreeSize );
mArticulationPoint.clear();
}
void assignNum(int src)
{
static int counter = 0;
vDFSTree[src].invested = true;
vDFSTree[src].v = src;
vDFSTree[src].num = counter++;
for ( vector<int >::iterator it=vGraph[src].begin(); it!=vGraph[src].end(); ++it )
{
if ( !vDFSTree[*it].invested )
{
vDFSTree[*it].v_parent = src;
assignNum( *it );
}
}
}
void assignLow(int src)
{
vDFSTree[src].low = vDFSTree[src].num;
for ( vector<int >::iterator it=vGraph[src].begin(); it!=vGraph[src].end(); ++it )
{
if ( vDFSTree[*it].num>vDFSTree[src].num ) //forward
{
assignLow(*it);
if ( vDFSTree[*it].low>=vDFSTree[src].num && vDFSTree[src].num!=0 )
mArticulationPoint.insert(std::make_pair(*it, *it));
vDFSTree[src].low = min( vDFSTree[src].low, vDFSTree[*it].low);
}
else//backward
{
if ( vDFSTree[src].v_parent!=*it )
vDFSTree[src].low = min(vDFSTree[src].low, vDFSTree[*it].num);
}
}
}
void PrintGraph(void)
{
int i(0);
cout << "graph: " << endl;
for ( vector<vector<int> >::iterator itvv=vGraph.begin(); itvv!=vGraph.end(); ++itvv )
{
cout << i++ << ": ";
for ( vector<int >::iterator itv=itvv->begin(); itv!=itvv->end(); ++itv )
cout << *itv << " ";
cout << endl;
}
}
void PrintDFSTree(void)
{
cout << "dfstree: "<< endl;
int i(0);
for ( i=0; i<iTreeSize; ++i )
cout << i << ": " << vDFSTree[i].num << " "<< vDFSTree[i].low << endl;
cout << "dfstree generation: "<< endl;
for ( i=0; i<iTreeSize; ++i )
cout << vDFSTree[i].v_parent << "-->" << vDFSTree[i].v << endl;
}
void PrintArti(void)
{
cout << "articulation point: " << endl;
for ( map<int, int>::iterator it=mArticulationPoint.begin(); it!=mArticulationPoint.end(); ++it)
{
cout << it->second << " " ;
}
cout << endl;
}
void PrintAll(void)
{
PrintGraph();
PrintDFSTree();
PrintArti();
}
void Dfst_Ex( int src)
{
InitTree();
assignNum(src);
assignLow(src);
PrintAll();
}
};
//测试文件
#include <iostream>
#include <cstdlib>
#include <vector>
#include "dfs.h"
#define _DFST_EX_
int main()
{
#ifdef _DFST_
{
using namespace dfst;
vector<int> v;
vGraph.clear();
//v0
v.clear();
v.push_back(1);
v.push_back(3);
v.push_back(4);
vGraph.push_back(v);
//v1
v.clear();
v.push_back(0);
v.push_back(2);
v.push_back(3);
vGraph.push_back(v);
//v2
v.clear();
v.push_back(1);
v.push_back(3);
v.push_back(4);
vGraph.push_back(v);
//v3
v.clear();
v.push_back(0);
v.push_back(1);
v.push_back(2);
vGraph.push_back(v);
//v4
v.clear();
v.push_back(0);
v.push_back(2);
v.push_back(3);
vGraph.push_back(v);
InitTree();
dfs(1);
PrintAll();
}
#endif
#ifdef _DFST_EX_
{
using namespace dfst_ex;
vector<int> v;
vGraph.clear();
//v0
v.clear();
v.push_back(1);
v.push_back(3);
vGraph.push_back(v);
//v1
v.clear();
v.push_back(0);
v.push_back(2);
vGraph.push_back(v);
//v2
v.clear();
v.push_back(1);
v.push_back(3);
v.push_back(6);
vGraph.push_back(v);
//v3
v.clear();
v.push_back(0);
v.push_back(2);
v.push_back(4);
v.push_back(5);
vGraph.push_back(v);
//v4
v.clear();
v.push_back(3);
v.push_back(5);
vGraph.push_back(v);
//v5
v.clear();
v.push_back(3);
v.push_back(4);
vGraph.push_back(v);
//v6
v.clear();
v.push_back(2);
vGraph.push_back(v);
Dfst_Ex(0);
}
#endif
system("pause");
return 0;
}