推荐到我的这篇博客中看完整版的。
该算法用于求解有向图的强连通分量,也就是强连通子图的个数。
算法实现摘自Kosaraju's algorithm - 百度百科:
#include <iostream> #include <stack> using namespace std; int map[511][511]; int nmap[511][511]; int visited[501]; stack<int> S; int N; int DFS1(int v) { visited[v] = 1; for (int i = 1; i <= N; i++) if (!visited[i] && map[v][i]) DFS1(i); S.push(v); return 0; } int DFS2(int v) { visited[v] = 1; for (int i = 1; i <= N; i++) if (!visited[i] && nmap[v][i]) DFS2(i); return 0; } int kosaraju() { memset(visited, 0, sizeof(visited)); for (int i = 1; i <= N; i++) if (!visited[i]) DFS1(i); int t = 0; memset(visited, 0, sizeof(visited)); while (!S.empty()) { int v = S.top(); S.pop(); printf("|%d|", v); if (!visited[v]) { t++; DFS2(v); } } return t; } int main() { int M, s, e; scanf_s("%d %d", &N, &M); memset(map, 0, sizeof(map)); memset(nmap, 0, sizeof(nmap)); for (int i = 0; i < M; i++) { scanf_s("%d %d", &s, &e); map[s][e] = 1; nmap[e][s] = 1; } printf(" %d ", kosaraju()); return 0; }
由于这里是使用邻接矩阵表示法的Kosaraju算法,因此算法时间复杂度为 $ O(V^2) $。使用邻接链表表示法则时间复杂度为 $ O(V + E) $。其中V为顶点个数,E为边个数。