强联通分量 Tarjan算法
2015-01-21 19:31
323 查看
//上交红书模板 // 图有节点0~n-1,共n个节点 vector< pair<int, int> > g; //存有向边 vector<int> ans; //染色结果 struct strongly_connected_components{ vector<int> &color; vector<int> Stack; int colorCnt, curr, *instack, *dfn, *low, *info, *next, *to; void dfs ( int x ) { dfn[x] = low[x] = ++ curr; Stack.push_back( x ); instack[x] = true; for ( int j = info[x]; j; j = next[j] ){ if ( ! instack[to[j]] ){ dfs ( to[j] ); low[x] = min ( low[x], low[to[j]] ); } else{ if ( instack[to[j]] == 1 ){ low[x] = min ( low[x], dfn[to[j]] ); } } } if ( low[x] == dfn[x] ){ while ( Stack.back() != x ){ color[Stack.back()] = colorCnt; instack[Stack.back()] = 2; Stack.pop_back(); } color[Stack.back()] = colorCnt++; instack[Stack.back()] = 2; Stack.pop_back(); } } strongly_connected_components ( const vector< pair<int, int> > &edgeList, int n, vector<int> &ans ) : color(ans) { color.resize( n ); instack = new int ; dfn = new int ; low = new int ; info = new int ; next = new int[(int)edgeList.size() + 5]; to = new int[(int)edgeList.size() + 5]; fill_n( info, n, 0 ); for ( size_t i = 0; i < edgeList.size(); ++ i ){ to[i+1] = edgeList[i].second; next[i+1] = info[edgeList[i].first]; info[edgeList[i].first] = i + 1; } fill_n( instack, n, 0 ); colorCnt = 0; curr = 0; for ( int i = 0; i < n; i ++ ){ if ( ! instack[i] ){ dfs ( i ); } } delete[] instack; delete[] dfn; delete[] low; delete[] info; delete[] next; delete[] to; } }; int main() { int m, n; while ( cin >> m >> n ){ int a, b; g.clear(); ans.clear(); for ( int i = 0; i < n; i ++ ){ cin >> a >> b; a --; b --; pair<int, int> tmp; tmp.first = a; tmp.second = b; g.push_back ( tmp ); } strongly_connected_components scc ( g, m, ans ); for ( int i = 0; i < ans.size(); i ++ ){ cout << ans[i] << ' '; } } }
网上tarjan模板
HDOJ1269
图中任意两点强联通
#define MAX_V 11111 int V, E; int dfn[MAX_V], low[MAX_V]; bool instack[MAX_V]; int din; int cnt; stack<int>s; vector<int>Edge[MAX_V]; void tarjan(int x){ instack[x] = true; dfn[x] = low[x] = din++; s.push(x); for (int i = 0; i < Edge[x].size(); i++){ int j = Edge[x][i]; if (!dfn[j]){ tarjan(j); low[x] = min(low[x], low[j]); } else if (instack[j]) low[x] = min(low[x], dfn[j]); } if (dfn[x] == low[x]){ cnt++; int tmp; do{ tmp = s.top(); s.pop(); instack[tmp] = false; }while (x != tmp); } } int main(){ while (scanf("%d %d", &V, &E) && (V || E)){ for (int i = 0; i < V; i++) Edge[i].clear(); for (int i = 0; i < E; i++){ int u, v; scanf("%d %d", &u, &v); Edge[u - 1].push_back(v - 1); } memset(dfn, 0, sizeof(dfn)); memset(instack, false, sizeof(instack)); din = 0; cnt = 0; for (int i = 0; i < V; i++){ if(!dfn[i]) tarjan(i); } if(cnt == 1) printf("Yes\n"); else printf("No\n"); } return 0; }
相关文章推荐
- POJ 2186 Popular Cows(强联通分量缩点+tarjan算法)
- 求有向图强联通分量--Tarjan算法
- Tarjan算法 (强联通分量 割点 割边)
- 强联通分量 缩点 tarjan算法
- 求解有向图的强联通分量--tarjan算法(tarjian求最小环模板)
- HDU 1269 迷宫城堡 (强联通分量,Tarjan算法)
- 强联通分量tarjan算法(模板)
- 强联通分量简讲(Tarjan算法)&&HDU 1269 迷宫城堡
- 强联通分量 Tarjan算法 模板
- 有向图的强联通分量 Tarjan算法模板
- 【POJ 1236 Network of Schools】强联通分量问题 Tarjan算法,缩点
- tarjan算法 求解强联通分量 POJ_2186_Popular Cows
- HDU1269 迷宫城堡 强联通分量Tarjan算法
- Tarjan算法---强联通分量
- Tarjan算法---强联通分量
- 求强联通分量——Tarjan算法
- 有向图的强联通分量Tarjan算法模版(hdu1269)
- 求解强联通分量 tarjan算法
- [BZOJ2959]长跑 LCT+双联通分量+并查集
- Tarjian算法求强联通分量【STL_stack的运用】