强连通分量(LRJ训练指南)
2013-08-26 23:10
239 查看
#include <iostream> #include <queue> #include <string> #include <cstdio> #include <cstring> #include <vector> #include <stack> #include <algorithm> using namespace std; const int maxn = 10000; int gn, gm; vector<int> gg[maxn]; int pre[maxn], low[maxn], sccno[maxn], dfs_clock, scc_cnt; stack<int> gs; void dfs(int u) { int i; pre[u] = low[u] = ++dfs_clock; gs.push(u); for(i = 0; i < (int)gg[u].size(); i++) { int v = gg[u][i]; if(!pre[v]) { dfs(v); low[u] = min(low[u], low[v]); } else if(!sccno[v]) { low[u] = min(low[u], low[v]);//min(low[u], low[v]); } } if(low[u] == pre[u]) { scc_cnt++; for(;;) { int x = gs.top(); gs.pop(); sccno[x] = scc_cnt; if(x == u) break; } } } void find_scc(int n) { dfs_clock = scc_cnt = 0; memset(sccno, 0, sizeof(sccno)); memset(pre, 0, sizeof(pre)); for(int i = 1; i <= n; i++) { if(!pre[i]) dfs(i); } } void print() { for(int i = 1; i <= gn; i++) { printf("i = %d -> %d\n", i, sccno[i]); } } int main() { int from, to; while(scanf("%d%d", &gn, &gm) ==2) { for(int i = 0; i < gm; i++) { scanf("%d%d", &from, &to); gg[from].push_back(to); } find_scc(gn); print(); } return 0; } /** 11 16 1 2 2 3 2 5 3 4 4 3 4 7 5 2 5 4 5 6 6 7 6 10 7 8 8 9 9 10 10 11 11 6 ***/
相关文章推荐
- 强连通分量(LRJ训练指南)
- LA3644,LA3027 并查集,LRJ训练指南
- 强连通分量SCC模版(LRJ)
- 【图论】【强连通分量】【Tarjan】pascal+邻接表
- 有向图强连通分量的Tarjan算法
- POJ 1523 SPF(割点所割连通分量数)
- 训练指南——数学专题一的总结
- 强连通分量和桥和割点——Tarjanの板子
- 树结构练习——判断给定森林中有多少棵树(相当于求连通分量个数)
- 凸包代码,摘自入门经典训练指南
- POJ 1523 SPF 求割点及对应的连通分量数
- 转一篇求图割点、连通分量的文章
- 极大强连通分量的Tarjan算法
- 强连通分量的三种算法和四种实现
- tarjan算法求强连通分量
- 数据结构实验:连通分量个数1488
- 数据结构实验:连通分量个数(并查集)
- tarjan算法----求强连通分量
- POJ-1904 King's Quest 强连通分量求完美匹配
- 【强连通分量缩点】poj 1236 Network of Schools