Critical Links

UVA 796 Critical Links

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82833#overview

题目大意:给你一个网络要求这里面的桥。
输入数据:
n 个点
点的编号  (与这个点相连的点的个数m)  依次是m个点的
 
输入到文件结束。
桥输出的时候需要排序
 
知识汇总:
桥:   无向连通图中,如果删除某条边后,图变成不连通了,则该边为桥。
求桥:
在求割点的基础上吗,假如一个边没有重边(重边 1-2, 1->2 有两次,那么 1->2 就是有两条边了,那么 1->2就不算是桥了)。
当且仅当 (u,v) 为父子边,且满足 dfn[u] < low[v]
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <cstring>

using namespace std;

#define INF 0xfffffff
#define N 11005
#define min(a,b) (a<b?a:b)

struct node
{
    int x, y;

    bool friend operator < (node A, node B)
    {
        if(A.x == B.x)
            return A.y < B.y;
        return A.x < B.x;
    }
}bridge[N];

vector<int> G[N];
int low[N], dfn[N], f[N], Time, n;

void init()
{
    for(int i = 0; i < n; i++)
        G[i].clear();

    Time = 0;
    memset(low, 0, sizeof(low));
    memset(dfn, 0, sizeof(dfn));
    memset(f, 0, sizeof(f));
}

void Tarjan(int u, int fa)
{
    low[u] = dfn[u] = ++Time;
    f[u] = fa;
    int len = G[u].size(), v;

    for(int i = 0; i < len; i++)
    {
        v = G[u][i];

        if(!low[v])
        {
            Tarjan(v, u);
            low[u] = min(low[u], low[v]);
        }
        else if(fa != v)
            low[u] = min(low[u], dfn[v]);
    }
}

void slove()
{
    int ans = 0;

    for(int i = 0; i < n; i++)  //可能不是一个连通图,所以每个点都要遍历
        if(!low[i])
            Tarjan(i, -1);
    for(int i = 0; i < n; i++)
    {
        int v = f[i];

        if(v != -1 && dfn[v] < low[i])   // 是桥的条件
        {
            bridge[ans].x = i;
            bridge[ans].y = v;
            if(bridge[ans].x > bridge[ans].y)
                swap(bridge[ans].x, bridge[ans].y);
            ans ++;
        }
    }
    sort(bridge, bridge+ans);

    printf("%d critical links
", ans);

    for(int i = 0; i < ans; i++)
        printf("%d - %d
", bridge[i].x, bridge[i].y);
    puts("");
}

int main()
{
    int a, b, m;

    while(scanf("%d", &n) != EOF)
    {
        init();

        for(int i = 0; i < n; i++)
        {
            scanf("%d (%d)", &a, &m);

            while(m--)
            {
                scanf("%d", &b);
                G[a].push_back(b);
                G[b].push_back(a);
            }
        }
        slove();
    }
    return 0;
}
 
让未来到来 让过去过去
原文地址:https://www.cnblogs.com/Tinamei/p/4707238.html