三:拓扑排序:
对于一个有向无环图G=(V,E)来说,其拓扑排序是G中所有结点的一种线性次序,该次序满足如下条件:如果图G包含边(u,v),其结点u在拓扑排序中处于结点v的前面(如果图G包含环路,则不可能排出一个线性次序)。可以将图的拓扑排序看做是将图的所有结点在一条水平线上排开,图的所有有向边都从左指向右。代码如下:
void dfs_visit(int source,vector<int>& color,list<int>& topo_sort,const vector<list<int>>& graph)
{
enum {WHITE,GRAY,BLACK};
color[source]=GRAY;
for(auto iter=graph[source].begin();iter!=graph[source].end();++iter)
{
int tmp=*iter;
if(color[tmp]==WHITE){
dfs_visit(tmp,color,topo_sort,graph);
}
}
color[source]=BLACK;
topo_sort.push_front(source);
}
list<int> topological_sort(const vector<list<int>> & graph)
{
enum {WHITE,GRAY,BLACK};
vector<int> color(graph.size(),WHITE);
list<int> topo_sort;
for(int v=0;v!=graph.size();++v) //对图中每个顶点v进行搜索;
if(color[v]==WHITE)
dfs_visit(v,color,topo_sort,graph);
return topo_sort;
}
四:强连通分量:
有向图G=(V,E)的强连通分量是一个属于集合V的最大结点集合C,对于该集合中的任意一对结点u和v来说,从结点u到结点v的路径和从结点v到结点u的路径同时存在,也就是说结点u和结点v可以相互抵达。深度优先搜索可以用于实现将有向图分解为一系列强连通分量。代码如下:
//to compute the tranpose of graph. G=(V,E)->G^T=(V,E^T),E^T={(u,v),(v,u)属于E}
vector<list<int>> graph_tranpose(const vector<list<int>>& graph)
{
vector<list<int>> tg(graph.size());
for(int v=0;v!=graph.size();++v)
for(auto iter=graph[v].begin();iter!=graph[v].end();++iter)
{
int tmp=*iter;
tg[tmp].push_back(v);
}
return tg;
}
void dfs_visit(int source,vector<int>& color,const vector<list<int>>& graph)
{
enum {WHITE,GRAY,BLACK};
color[source]=GRAY;
for(auto iter=graph[source].begin();iter!=graph[source].end();++iter)
{
int tmp=*iter;
if(color[tmp]==WHITE){
dfs_visit(tmp,color,graph);
}
}
color[source]=BLACK;
cout<<source<<" ";
}
void strongly_connected_components(const vector<list<int>>& graph)
{
auto topo_sort=topological_sort(graph); //输出的是v.f按降序排列的顶点v;
auto tg=graph_tranpose(graph); //输出图graph的转置;
//to conduct the depth first search on the tranposed graph tg.
enum {WHITE,GRAY,BLACK};
vector<int> color(graph.size(),WHITE);
// to consider the vertices in order of decreasing v.f
for(auto iter=topo_sort.begin();iter!=topo_sort.end();++iter)
{
int v=*iter;
if(color[v]==WHITE){
cout<<"strongly connected component: ";
dfs_visit(v,color,tg);//输出一棵深度优先树.
cout<<endl;
}
}
}