參考閱讀:
如何理解kosaraju演算法? - 簡緻的回答 - 知乎
kosaraju演算法步驟:
用dfs後序遍歷原圖的反轉圖,得到後序遍歷順序
用得到的後序遍歷順序對原圖dfs
**實現
棧和圖的定義
const
int maxv =
100;
/*定義棧*/
typedef
struct snode
* stack;
/*定義邊*/
typedef
struct enode
* edge;
/*定義鄰接點*/
struct adjvnode
;/*定義鄰接表頭*/
typedef
struct vnode adjlist[maxv]
;/*定義圖*/
typedef
struct gnode
* lgraph;
對棧需要的操作
/*創造乙個新的棧*/
stack createstack
(int maxsize)
/*將x壓入棧*/
void
push
(stack s, string x)
/*返回元素x是否在棧中位置, 若不在返回-1*/
intfinds
(stack s, string x)
/*將邊由string型加入對應的int型順序編號*/
void
edge_code
(edge e, stack s)
else
e->v1 = k;
//得到已有v1的編號
k =finds
(s, e-
>vb);if
(k <0)
//如果頂點不在棧中, 壓入棧
else
e->v2 = k;
//得到已有v2的編號
}
圖的操作
/*創造新的無邊圖*/
lgraph creategraph
(int nv)
/*邊的插入*/
void
insertedge
(lgraph g, edge e)
/*鍵入建立圖*/
lgraph buildgraph()
delete e;
delete
s->data;
delete s;
return g;
}/*刪除圖*/
void
deletegraph
(lgraph g)
}delete g;
}
輸出圖的物理結構
/*遍歷輸出圖的鄰接表圖的物理結構*/
void
showgraph
(lgraph g)
cout <<
"null"
<< endl;
}}
得到圖g的倒置圖gr
/*返回圖g的倒置圖gr*/
lgraph reversegraph
(lgraph g)
}delete e;
return gr;
}
kosaraju演算法
/*找出字元x在圖g中的編號*/
intfindg
(lgraph g, string x)
void
dfs(lgraph g,
int u, stack s)
push
(s, g-
>l[u]
.data);}
void
kosaraju
(lgraph g)
}deletegraph
(g);
deletegraph
(gr)
;delete
reverse;
delete
s->data;
delete s;
}
程式執行輸入
13220
1052
0233
2354
2435
4606
4697
6788
7899
1091110
1211411
1212
9
執行結果
完整**
#include
#include
#include
#include
using
namespace std;
const
int maxv =
100;
/*定義棧*/
typedef
struct snode
* stack;
/*定義邊*/
typedef
struct enode
* edge;
/*定義鄰接點*/
struct adjvnode
;/*定義鄰接表頭*/
typedef
struct vnode adjlist[maxv]
;/*定義圖*/
typedef
struct gnode
* lgraph;
/*創造乙個新的棧*/
stack createstack
(int maxsize)
/*將x壓入棧*/
void
push
(stack s, string x)
/*返回元素x是否在棧中位置, 若不在返回-1*/
intfinds
(stack s, string x)
/*將邊由string型加入對應的int型順序編號*/
void
edge_code
(edge e, stack s)
else
e->v1 = k;
//得到已有v1的編號
k =finds
(s, e-
>vb);if
(k <0)
//如果頂點不在棧中, 壓入棧
else
e->v2 = k;
//得到已有v2的編號
}/*創造新的無邊圖*/
lgraph creategraph
(int nv)
/*邊的插入*/
void
insertedge
(lgraph g, edge e)
/*鍵入建立圖*/
lgraph buildgraph()
delete e;
delete
s->data;
delete s;
return g;
}/*遍歷輸出圖的鄰接表圖的物理結構*/
void
showgraph
(lgraph g)
cout <<
"null"
<< endl;}}
/*刪除圖*/
void
deletegraph
(lgraph g)
}delete g;
}/*返回圖g的倒置圖gr*/
lgraph reversegraph
(lgraph g)
}delete e;
return gr;
}/*找出字元x在圖g中的編號*/
intfindg
(lgraph g, string x)
void
dfs(lgraph g,
int u, stack s)
push
(s, g-
>l[u]
.data);}
void
kosaraju
(lgraph g)
}delete
reverse;
delete
s->data;
delete s;
}int
main()
強連通分量 Kosaraju演算法
求有向圖的強連通分量除了大家熟知的trajan,還可以用kosaraju 先說演算法流程 1,對原圖dfs一遍,並將出棧順序的逆序作為 偽拓撲序 2,對原圖夠構反向圖 3,按偽拓撲序在反向圖上dfs,新遍歷到的點都屬於同乙個強聯通分量。正確性證明 s在反向圖上dfs能夠遍歷到t,說明存在t到s的路徑...
Kosaraju演算法 強連通分量
有向圖的極大強連通子圖,稱為強連通分量。子圖指的是選取v的乙個子集v 以及e當中所有滿足u,v v 的邊集e 所指代的圖.我們需要找出一幅有向圖當中的所有強連通分量。乙個最樸素的演算法 構造乙個傳遞閉包 也就是陣列aij表示i能否到達j 然後把aij aji 1的節點置於同乙個強連通分量當中 這個演...
強連通分量 Kosaraju
芝士 有向圖強連通分量在有向圖g中,如果兩個頂點vi,vj間 vi vj 有一條從vi到vj的有向路徑,同時還有一條從vj到vi的有向路徑,則稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。有向圖的極大強連通子圖,稱為強連通分量。如圖中1...