Critical Links
分类:
Graph
1.题意概述
- 给你一个图,要你按顺序求出图中所有的桥。
2.解题思路
- 根据Tarjan求割边的算法找出所有
low[v]>dfn[u]
边就行,算是一道入门题。
3.AC代码
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define maxn 10010
/* head */
struct Edge {
int to, next;
bool cut;
} E[maxn << 1];
int head[maxn], cnt;
int dfn[maxn], low[maxn], sec;
int bridge, n;
void init() {
memset(head, -1, sizeof head);
memset(dfn, 0, sizeof dfn);
memset(low, 0, sizeof low);
cnt = sec = bridge = 0;
}
void addedge(int u, int v) {
E[cnt].to = v;
E[cnt].next = head[u];
E[cnt].cut = 0;
head[u] = cnt++;
}
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++sec;
for (int i = head[u]; ~i; i = E[i].next) {
int v = E[i].to;
if (v != fa) {
if (!dfn[v]) {
tarjan(v, u);
low[u] = min(low[u], low[v]);
if (low[v] > dfn[u]) {
++bridge;
E[i].cut = 1;
E[i ^ 1].cut = 1;
}
}
else low[u] = min(low[u], dfn[v]);
}
}
}
int main() {
while (~scanf("%d", &n)) {
init();
rep(i, 0, n) {
int u, m;
scanf("%d (%d)", &u, &m);
++u;
while (m--) {
int v;
scanf("%d", &v);
++v;
addedge(u, v);
addedge(v, u);
}
}
rep(i, 1, n + 1) {
if (!dfn[i]) tarjan(i, i);
}
printf("%d critical links\n", bridge);
vector<PII> ans;
rep(u, 1, n + 1) {
for (int i = head[u]; ~i; i = E[i].next) {
int v = E[i].to;
if (E[i].cut && v > u) ans.pb(mp(u, v));
}
}
sort(All(ans));
int sz = SZ(ans);
rep(i, 0, sz) printf("%d - %d\n", ans[i].fi - 1, ans[i].se - 1);
puts("");
}
return 0;
}