1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include <iostream> #include <string.h> #include <algorithm> using namespace std; const int maxn = 1e5 + 10; int head[maxn], next1[maxn << 1], ver[maxn << 1]; int dfn[maxn], low[maxn]; int n,tot,num; bool bridge[maxn << 1];
void edgeadd(int x,int y) { ver[++tot] = y; next1[tot] = head[x]; head[x] = tot; } void tarjan(int x,int in_edge) { dfn[x] = low[x] = ++num; for (int i = head[x]; i; i = next1[i]) { int y = ver[i]; if (!dfn[y]) { tarjan(y, i); low[x] = min(low[x], low[y]);
if (low[y] > dfn[x]) { bridge[i] = bridge[i ^ 1] = 1; } } else if (i != (in_edge ^ 1)) low[x] = min(dfn[y],low[x]); } } void init() { tot = 1; num = 0;
memset(low,0,sizeof low); memset(dfn,0,sizeof dfn);
memset(head, 0, sizeof head); memset(next1, 0, sizeof next1); memset(ver,0,sizeof ver);
memset(bridge,0,sizeof bridge); } int main() {
while (~scanf("%d",&n)) { init(); if (n == 0) { printf("0 critical links\n\n"); continue; } for (int i = 1; i <= n; i++) { int cur, cnt; scanf("%d (%d)",&cur,&cnt); cur++; for (int j = 1; j <= cnt; j++) { int to; scanf("%d", &to); to++; if (to <= cur) continue; edgeadd(cur, to); edgeadd(to,cur); } } for (int i = 1; i <= n; i++) if (!dfn[i]) tarjan(i,0); int ans = 0; for (int i = 2; i < tot; i+=2) if (bridge[i]) ans++; printf("%d critical links\n",ans); for (int i = 2; i < tot; i += 2) if (bridge[i]) printf("%d - %d\n",ver[i^1] - 1,ver[i] - 1); printf("\n"); } return 0; }
|