UVA796- Critical Links(无向图的桥)

题目链接

题意: 给出一个无向图,按顺序输出桥

思路:求出所有的桥,然后按顺序输出即可

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <utility>
#include <algorithm>

using namespace std;

const int MAXN = 10005;

struct Edge{
    int to, next;
    bool cut;
}edge[MAXN * 10];
int head[MAXN], tot;
int Low[MAXN], DFN[MAXN], Stack[MAXN];
int Index, top;
bool Instack[MAXN];
bool cut[MAXN];
int add_block[MAXN];
int bridge;

void addedge(int u, int v) {
    edge[tot].to = v;
    edge[tot].next = head[u];
    edge[tot].cut = false;
    head[u] = tot++;
}

void Tarjan(int u, int pre) {
    int v;
    Low[u] = DFN[u] = ++Index;
    Stack[top++] = u;
    Instack[u] = true;
    int son = 0;
    for (int i = head[u]; i != -1; i = edge[i].next) {
        v = edge[i].to;
        if (v == pre) continue;
        if (!DFN[v]) {
            son++;
            Tarjan(v, u);
            if (Low[u] > Low[v]) Low[u] = Low[v];
            if (Low[v] > DFN[u]) {
                bridge++;
                edge[i].cut = true;
                edge[i^1].cut = true;
            }
            if (u != pre && Low[v] >= DFN[u]) {
                cut[u] = true;
                add_block[u]++;
            }
        }
        else if (Low[u] > DFN[v])
            Low[u] = DFN[v];
    }
    if (u == pre && son > 1) cut[u] = true;
    if (u == pre) add_block[u] = son - 1;
    Instack[u] = false;
    top--;
}

void init() {
    memset(head, -1, sizeof(head));
    memset(DFN, 0, sizeof(DFN));
    memset(Instack, false, sizeof(Instack));
    memset(add_block, 0, sizeof(add_block));
    memset(cut, false, sizeof(cut));
    tot = 0;
    Index = top = 0;
    bridge = 0;
}

void solve(int N) {
    for (int i = 1; i <= N; i++)
        if (!DFN[i])
            Tarjan(i, i);

    printf("%d critical links\n",bridge);
    vector<pair<int, int> > ans;
    for (int u = 1; u <= N; u++)
        for (int i = head[u]; i != -1; i = edge[i].next)
            if (edge[i].cut && edge[i].to > u) {
                ans.push_back(make_pair(u, edge[i].to));
            }

   sort(ans.begin(), ans.end());
   for(int i = 0;i < ans.size();i++)
       printf("%d - %d\n",ans[i].first-1,ans[i].second-1);
   printf("\n");
}

int main() {
    int n;
    while (scanf("%d", &n) == 1) {
        init();
        int u, k, v;
        for (int i = 1; i <= n; i++) {
            scanf("%d (%d)", &u, &k);
            u++;
            while (k--) {
                scanf("%d", &v);
                v++;
                addedge(u, v);
                addedge(v, u);
            }
        }
        solve(n);
    }
    return 0;
}

时间: 2024-08-03 23:29:40

UVA796- Critical Links(无向图的桥)的相关文章

UVA 796 Critical Links(无向图求桥)

题目来源: UVa Online Judgehttps://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

UVA796:Critical Links(输出桥)

Critical Links 题目链接:https://vjudge.net/problem/UVA-796 Description: In a computer network a link L, which interconnects two servers, is considered critical if there are at least two servers A and B such that all network interconnection paths between

[UVA796]Critical Links(割边, 桥)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=737 求桥的数量,也就是割边的数量.输入有点小坑,左右括号外必须得有个空格才行,起初以为是转义的问题. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8

UVA796 - Critical Links(Tarjan求桥)

In a computer network a link L, which interconnects two servers, is considered critical if there are atleast two servers A and B such that all network interconnection paths between A and B pass through L.Removing a critical link generates two disjoin

UVA 796 - Critical Links【求桥】

link:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=737 题意: 求桥的数目及边,要求输出边的点的次序由小到大 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include

UVA 796 - Critical Links (求桥按序输出)

tanjar求图中的桥,然后排序输出. 代码: #include<iostream> #include<cstdio> #include<string> #include<cmath> #include<queue> #include<stack> #include<map> #include<cstring> #include<algorithm> #define rep(i,a,b) for(i

Light OJ - 1026 - Critical Links(图论-Tarjan算法求无向图的桥数) - 带详细注释

 原题链接   无向连通图中,如果删除某边后,图变成不连通,则称该边为桥. 也可以先用Tajan()进行dfs算出所有点 的low和dfn值,并记录dfs过程中每个 点的父节点:然后再把所有点遍历一遍, 看其low和dfn,满足dfn[ fa ]<low[ i ](0<i<=n, i 的 father为fa) -- 则桥为fa-i. 找桥的时候,要注意看有没有重边:有重边,则不是桥. 另外,本题的题意及测试样例中没有重边,所以不用考虑重边. 带详细注释的题解: #include<s

【lightoj-1026】Critical Links(桥)

题意: 给出无向图,求桥的模板题. #include <bits/stdc++.h> using namespace std; const int N = 10004; int dfn[N], low[N];//时间戳;low[i]以i为根子树的最小祖先的时间戳 bool vis[N]; vector<int>V[N]; int n, num, c; pair<int, int>P[N]; void dfs(int s, int f) { low[s] = dfn[s]

UVA 796 Critical Links —— (求割边(桥))

和求割点类似,只要把>=改成>即可.这里想解释一下的是,无向图没有重边,怎么可以使得low[v]=dfn[u]呢?只要它们之间再来一个点即可. 总感觉图论要很仔细地想啊- -一不小心就弄混了.. 另外从这题发现,代码还是写成模块化比较好,比如solve一个函数,init一个函数等等,这样可以避免很多东西忘记写,比方说dfn或者G的清空等等.. 代码如下: 1 #include <stdio.h> 2 #include <stack> 3 #include <alg