UVA-796 Critical Links 无向图求桥

题目大意:给出一张无向图(不一定联通,可能有重边),求出桥的数目,并按节点升序输出桥

题目思路:Tarjan求出桥,注意去掉重边

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<iostream>
#include<algorithm>
#define MAXSIZE 10005
#define LL long long

using namespace std;

vector<vector<int> >G;
int vis[MAXSIZE],low[MAXSIZE],dfn[MAXSIZE],pre[MAXSIZE],Time,n,ans,son;

struct node
{
    int a,b;
} point[MAXSIZE];

void Tarjan(int u,int fa)
{
    pre[u]=fa;
    low[u]=dfn[u]=++Time;
    int len=G[u].size(),v,op=0;
    for(int i=0; i<len; i++)
    {
        v=G[u][i];
        if(v==fa && !op)//若不存在重边那么执行这一步,low[u]将不被更新
        {
            op=1;
            continue;
        }
        if(!dfn[v])
        {
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
        }
        else//若存在重边执行这一步,low[u]将被更新,那么查找时便不满足dnf[pre[u]] < low[u],不计入桥
        {
            low[u]=min(low[u],dfn[v]);
        }
    }
}

void Init()
{
    memset(low,0,sizeof(low));
    memset(dfn,0,sizeof(dfn));
    memset(vis,0,sizeof(vis));
    memset(pre,-1,sizeof(pre));
    G.clear();
    G.resize(n+1);
    Time=0;
    ans=0;
    son=0;
}

bool cmp(struct node A,struct node B)
{
    if(A.a != B.a)
        return A.a > B.a?false:true;
    return A.b > B.b?false:true;
}

int main()
{
    int a,b,m;
    while(scanf("%d",&n)!=EOF)
    {
        Init();
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a);
            getchar();
            getchar();
            scanf("%d",&m);
            getchar();
            while(m--)
            {
                scanf("%d",&b);
                G[a].push_back(b);
                //G[b].push_back(a);
            }
        }
        for(int i=0; i<n; i++)
        {
            if(!dfn[i])
            {
                Tarjan(i,-1);
            }
        }
        for(int i=0; i<n; i++)
        {
            int v=pre[i];
            if(dfn[v]<low[i] && v!=-1)
            {
                point[ans].a=min(i,v);
                point[ans].b=max(i,v);
                ans++;
            }
        }
        printf("%d critical links\n",ans);
        sort(point,point+ans,cmp);
        for(int i=0; i<ans; i++)
        {
            printf("%d - %d\n",point[i].a,point[i].b);
        }
        printf("\n");
    }
    return 0;
}
View Code

 

posted @ 2017-03-09 20:32  声声醉如兰  阅读(108)  评论(0编辑  收藏  举报