zoukankan      html  css  js  c++  java
  • UVA 796 Critical Links(无向图求桥)

    题目来源:

    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
    ", k);
            for (i = 0; i < k; i++) printf("%d - %d
    ", no[i].x, no[i].y);
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    使用正则表达式实现(加减乘除)计算器(C#实现)
    asp.net core中间件工作原理
    WPF
    WPF
    WPF
    WPF
    WPF 3D Cube及点击交互
    WPF 3D足球导览
    WPF 3D 球面导览
    WPF 3D球及进阶玩法
  • 原文地址:https://www.cnblogs.com/syhandll/p/4707050.html
Copyright © 2011-2022 走看看