无向图点双连同分量BCC模版(LRJ)
2013-03-30 17:16
253 查看
#include<cstdio> #include<stack> #include<vector> #include<algorithm> #include<cstring> using namespace std; const int maxn = 1000 + 10; struct Edge { int u, v; }; int pre[maxn], iscut[maxn], bccno[maxn], dfs_clock, bcc_cnt; // 割顶的bccno无意义 vector<int> G[maxn], bcc[maxn]; stack<Edge> S; int dfs(int u, int fa) { int lowu = pre[u] = ++dfs_clock; int child = 0; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; Edge e = (Edge){u, v}; if(!pre[v]) { // 没有访问过v S.push(e); child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); // 用后代的low函数更新自己 if(lowv >= pre[u]) { iscut[u] = true; bcc_cnt++; bcc[bcc_cnt].clear(); for(;;) { Edge x = S.top(); S.pop(); if(bccno[x.u] != bcc_cnt) { bcc[bcc_cnt].push_back(x.u); bccno[x.u] = bcc_cnt; } if(bccno[x.v] != bcc_cnt) { bcc[bcc_cnt].push_back(x.v); bccno[x.v] = bcc_cnt; } if(x.u == u && x.v == v) break; } } } else if(pre[v] < pre[u] && v != fa) { S.push(e); lowu = min(lowu, pre[v]); // 用反向边更新自己 } } if(fa < 0 && child == 1) iscut[u] = 0; return lowu; } void find_bcc(int n) { // 调用结束后S保证为空,所以不用清空 memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); memset(bccno, 0, sizeof(bccno)); dfs_clock = bcc_cnt = 0; for(int i = 0; i < n; i++) if(!pre[i]) dfs(i, -1); }
每个孤点的bccno都是0,bcc从1开始编号,图中的节点得从0开始编号.
相关文章推荐
- 强连通分量SCC模版(LRJ)
- HDU 1269 迷宫城堡 (裸的Tarjan算法求强连通分量, 可作模版)
- 【图论算法及模版】割点,割边,强联通分量,点双联通分量,边双联通分量
- 无向图的连通分量(BCC)模版
- hdu1269(强联通分量模版)
- 最大匹配BPM模版(LRJ)
- 强连通分量(SCC)模版
- codevs爱在心中(强联通分量,缩点,求出度为0的点)缩点模版
- 二分图最小点覆盖模版(LRJ)
- 强连通分量(LRJ训练指南)
- Strictly Positive Matrix CodeForces - 402E 强联通分量 模版
- hdu 1269 迷宫城堡 强连通分量模版
- 最小有向生成树--朱刘算法模版(LRJ)
- 重连通分量模版
- 【图论算法及模版】割点,割边,强联通分量,点双联通分量,边双联通分量
- TwoSAT模版(LRJ)
- 强连通分量(LRJ训练指南)
- HDU 1269 迷宫城堡 【强联通分量(模版题)】
- UVALive4287 强联通分量新模版
- vijos1022(强联通分量模版题)