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

三:拓扑排序:

对于一个有向无环图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;
                }
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值