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; }

 

posted @ 2018-07-12 21:56  WTSRUVF  阅读(202)  评论(0编辑  收藏  举报