强连通分量_Kosaraju算法
2012-01-26 23:42
295 查看
//将图G通过深度优先遍历,记录退出访问的序列(此序列为一逆拓扑序),并逐一入栈(拓扑序),将图G转置(即边的方向反转),对栈顶每个元素进行逐一深度遍历,遍历到的元素即为一个强连通分量;如果已经之前被遍历,则不再重复遍历。(这里使用邻接矩阵,可以使用十字链表来实现正逆矩阵)
//正确性证明,见网络
#include <iostream> 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; }
//正确性证明,见网络
相关文章推荐
- Kosaraju算法求最强连通分量
- 半连通分量--Tarjan/Kosaraju算法
- Kosaraju算法求有向强连通分量,缩点后是DAG的拓扑序列(从小到大)
- 有向图----强连通分量问题(Kosaraju算法)
- 强连通分量 Kosaraju算法
- 强连通分量 Kosaraju算法
- 强连通分量(Kosaraju算法)
- [图论] 有向图强连通分量 (kosaraju算法,Tarjan算法)
- 强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)
- 求有向图的强连通分量个数 之 Kosaraju算法
- poj2186Popular Cows(Kosaraju算法--有向图的强连通分量的分解)
- 强连通分量——Kosaraju算法
- 强连通分量——[Kosaraju算法]
- Kosaraju算法解析: 求解图的强连通分量
- 有向图的强连通分量之Kosaraju算法
- 一句话之--tarjan算法、kosaraju算法,求强连通分量
- 强连通分量 -- Kosaraju算法
- 有向图强连通分量的Tarjan算法和Kosaraju算法
- 强连通分量——kosaraju算法
- 强连通分量-kosaraju算法