UVA 796 Critical Links
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82833#overview
题目大意:给你一个网络要求这里面的桥。
输入数据:
n 个点
点的编号 (与这个点相连的点的个数m) 依次是m个点的
输入到文件结束。
桥输出的时候需要排序
知识汇总:
桥: 无向连通图中,如果删除某条边后,图变成不连通了,则该边为桥。
求桥:
在求割点的基础上吗,假如一个边没有重边(重边 1-2, 1->2 有两次,那么 1->2 就是有两条边了,那么 1->2就不算是桥了)。
当且仅当 (u,v) 为父子边,且满足 dfn[u] < low[v]
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <stack> #include <cstring> using namespace std; #define INF 0xfffffff #define N 11005 #define min(a,b) (a<b?a:b) struct node { int x, y; bool friend operator < (node A, node B) { if(A.x == B.x) return A.y < B.y; return A.x < B.x; } }bridge[N]; vector<int> G[N]; int low[N], dfn[N], f[N], Time, n; void init() { for(int i = 0; i < n; i++) G[i].clear(); Time = 0; memset(low, 0, sizeof(low)); memset(dfn, 0, sizeof(dfn)); memset(f, 0, sizeof(f)); } void Tarjan(int u, int fa) { low[u] = dfn[u] = ++Time; f[u] = fa; int len = G[u].size(), v; for(int i = 0; i < len; i++) { v = G[u][i]; if(!low[v]) { Tarjan(v, u); low[u] = min(low[u], low[v]); } else if(fa != v) low[u] = min(low[u], dfn[v]); } } void slove() { int ans = 0; for(int i = 0; i < n; i++) //可能不是一个连通图,所以每个点都要遍历 if(!low[i]) Tarjan(i, -1); for(int i = 0; i < n; i++) { int v = f[i]; if(v != -1 && dfn[v] < low[i]) // 是桥的条件 { bridge[ans].x = i; bridge[ans].y = v; if(bridge[ans].x > bridge[ans].y) swap(bridge[ans].x, bridge[ans].y); ans ++; } } sort(bridge, bridge+ans); printf("%d critical links ", ans); for(int i = 0; i < ans; i++) printf("%d - %d ", bridge[i].x, bridge[i].y); puts(""); } int main() { int a, b, m; while(scanf("%d", &n) != EOF) { init(); for(int i = 0; i < n; i++) { scanf("%d (%d)", &a, &m); while(m--) { scanf("%d", &b); G[a].push_back(b); G[b].push_back(a); } } slove(); } return 0; }