您的位置:首页 > 其它

第22章:基本的图算法—拓扑排序和有向图强连通分量

2016-07-14 18:33 351 查看

三:拓扑排序:

对于一个有向无环图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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: