Kosaraju_Algorithm求有向图的强连通分量

有向图强连通分量在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。


Kosaraju算法思路

这个算法可以说是最容易理解,最通用的算法,其比较关键的部分是同时应用了原图G和反图GT。步骤1:先用对原图G进行深搜形成森林(树),步骤2:然后任选一棵树对其进行深搜(注意这次深搜节点A能往子节点B走的要求是EAB存在于反图GT),能遍历到的顶点就是一个强连通分量。余下部分和原来的森林一起组成一个新的森林,继续步骤2直到 没有顶点为止。

伪代码
Kosaraju_Algorithm:
step1:对原图G进行深度优先遍历,记录每个节点的离开时间。
step2:选择具有最晚离开时间的顶点,对反图GT进行遍历,删除能够遍历到的顶点,这些顶点构成一个强连通分量。
step3:如果还有顶点没有删除,继续step2,否则算法结束

C++代码

#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 110;
typedef int AdjTable[MAXN]; //邻接表类型
int n;
bool flag[MAXN]; //访问标志数组
int belg[MAXN]; //存储强连通分量,其中belg[i]表示顶点i属于第belg[i]个强连通分量
int numb[MAXN]; //结束时间标记,其中numb[i]表示离开时间为i的顶点
AdjTable adj[MAXN], radj[MAXN]; //邻接表,逆邻接表
//用于第一次深搜,求得numb[1..n]的值
void VisitOne(int cur, int &sig)
{
    flag[cur] = true;
    for ( int i=1; i<=adj[cur][0]; ++i )
    {
        if ( false==flag[adj[cur][i]] )
        {
            VisitOne(adj[cur][i],sig);
        }
    }
    numb[++sig] = cur;
}
//用于第二次深搜,求得belg[1..n]的值
void VisitTwo(int cur, int sig)
{
    flag[cur] = true;
    belg[cur] = sig;
    for ( int i=1; i<=radj[cur][0]; ++i )
    {
        if ( false==flag[radj[cur][i]] )
        {
            VisitTwo(radj[cur][i],sig);
        }
    }
}
//Kosaraju算法,返回为强连通分量个数
int Kosaraju_StronglyConnectedComponent()
{
    int i, sig;
    //第一次深搜
    memset(flag+1,0,sizeof(bool)*n);
    for ( sig=0,i=1; i<=n; ++i )
    {
        if ( false==flag[i] )
        {
            VisitOne(i,sig);
        }
    }
    //第二次深搜
    memset(flag+1,0,sizeof(bool)*n);
    for ( sig=0,i=n; i>0; --i )
    {
        if ( false==flag[numb[i]] )
        {
            VisitTwo(numb[i],++sig);
        }
    }
    return sig;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值