Network POJ - 3694 (連通圖標求橋)


有上述兩個數組定義可知:對於某點root,其有一兒子v,則有:

1.     如果dfn[root]<=low[v]此點是割點(對於dfs樹的根,即最初節點需要兩個兒子才是割點)

2.     如果dfn[root]<low[v],連接root與v的邊是橋。






#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <vector> #include <stack> #include <algorithm> #include <cmath> #define mem(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 10010, INF = 0x7fffffff; int pre[maxn], low[maxn], iscut[maxn]; int dfs_clock, n, cnt; vector<int> G[maxn]; struct edge { int u, v; }Edge[maxn]; int cmp(edge a, edge b) { if(a.u == b.u) return a.v < b.v; return a.u < b.u; } 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]; if(!pre[v]) { child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if(lowv > pre[u]) { iscut[u] = 1; Edge[cnt].u = u, Edge[cnt].v = v; if(Edge[cnt].u > Edge[cnt].v) swap(Edge[cnt].u, Edge[cnt].v); cnt++; } } else if(pre[v] < pre[u] && v != fa) lowu = min(lowu, pre[v]); } if(fa < 0 && child == 1) iscut[u] = 0; low[u] = lowu; return lowu; } void init() { cnt = 0; dfs_clock = 0; mem(pre, 0); mem(low, 0); mem(iscut, 0); for(int i=0; i<=n; i++) G[i].clear(); } int main() { while(cin>> n) { init(); for(int i=0; i<n; i++) { int u, d, v; scanf("%d (%d)", &u, &d); for(int i=0; i<d; i++) { cin>> v; G[u].push_back(v); G[v].push_back(u); } } for(int i=0; i<n; i++) if(!pre[i]) dfs(i, -1); sort(Edge, Edge+cnt, cmp); printf("%d critical links\n",cnt); for(int i=0; i<cnt; i++) cout<< Edge[i].u << " - " << Edge[i].v <<endl; cout<<endl; } return 0; }

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: