UVA796

来源:互联网 发布:python多进程读取文件 编辑:程序博客网 时间:2024/06/03 12:28

题目链接

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