強連通分量Kosaraju演算法

2021-10-03 19:22:40 字數 4427 閱讀 3736

參考閱讀:

如何理解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...