题目来源:
UVa Online Judge
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=737
求一个连通图中必不可少的路径:
#include<stdio.h> #include<algorithm> #include<vector> #include<string.h> #define N 1010 using namespace std; struct node { int x, y; } no[N]; int dfn[N], low[N]; int f[N], Time, n; vector<vector<int> >G; void Init() { G.clear(); G.resize(n+1); memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(f, 0, sizeof(f)); Time = 0; } void Tarjan(int u, int fa) { int i, len, v; dfn[u] = low[u] = ++Time; f[u] = fa; len = G[u].size(); for (i = 0; i < len; i++) { v = G[u][i]; if (!dfn[v]) { Tarjan(v, u); low[u] = min(low[u], low[v]); } else if (v != fa) low[u] = min(low[u], dfn[v]); } } int cmp(node a, node b) { if (a.x != b.x) return a.x < b.x; return a.y < b.y; } //从小到大排序 int main () { int a, b, m, k, i, ni, mn; while (scanf("%d", &n) != EOF) { k = 0; Init(); mn = n; while (mn--) { scanf("%d (%d)", &a, &m); while (m--) { scanf("%d", &b); G[a].push_back(b); G[b].push_back(a); } } for (i = 0; i < n; i++) if (!dfn[i]) Tarjan(i, -1); //可能出现多个连通图的现象,需要每次进行查找,一次查找后该连通图的节点的dfn都不为0,借此可以判断是否还有其他连通图 for (i = 0; i < n; i++) { ni = f[i]; if (ni != -1 && dfn[ni] < low[i]) //父节点为-1说明该点为根节点,与其父节点不可能存在桥 { //dfn[ni]==low[i]说明i还有其他路径到ni,则说明i-ni不属于桥 no[k].x = i; no[k].y = ni; if (i > ni) swap(no[k].x, no[k].y); k++; } } sort(no, no+k, cmp); printf("%d critical links\n", k); for (i = 0; i < k; i++) printf("%d - %d\n", no[i].x, no[i].y); printf("\n"); } return 0; }
时间: 2025-01-02 17:41:08