hdu3849 By Recognizing These Guys, We Find Social Networks Useful

无向图求桥边数量,按照题目输入顺序输出桥边。

注意存的brig和边的对应关系。


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#pragma comment(linker, "/STACK:16777216")
#define eps 1e-6
#define ll long long
using namespace std;
#define M 200003
#define N 10003

int head[N],num,dfn[N],low[N],n,m,idx,brig[M<<1],bum;
struct edge
{
    int st,ed,next;
}E[M<<1];

void addedge(int x,int y)
{
    E[num].st=x;
    E[num].ed=y;
    E[num].next=head[x];
    head[x]=num++;
}

void tarjan(int u,int father)
{
    int i,v;
    low[u]=dfn[u]=idx++;
    for(i=head[u];i!=-1;i=E[i].next)
    {
        v=E[i].ed;
        if(v==father)continue;
        if(dfn[v]==-1)
        {
            tarjan(v,u);
            low[u]=low[u]>low[v]?low[v]:low[u];
            if(low[v]>dfn[u])//存第bum个桥对应边的编号
                brig[bum++]=i;
        }
        else low[u]=low[u]>dfn[v]?dfn[v]:low[u];
    }
}

void init()
{
    memset(dfn,-1,sizeof dfn);
    memset(head,-1,sizeof head);
    num=bum=idx=0;
}

string hash[N];
string s1,s2;

bool cmp(int a,int b)
{
    return a<b;
}

int main()
{
    int icy,i,cnt;
    scanf("%d",&icy);
    while(icy--)
    {
        scanf("%d%d",&n,&m);
        init();
        map<string,int> mp;
        cnt=1;
        for(i=0;i<m;i++)
        {
            cin>>s1>>s2;
            if(!mp[s1])
                hash[cnt]=s1,mp[s1]=cnt++;
            if(!mp[s2])
                hash[cnt]=s2,mp[s2]=cnt++;
            addedge(mp[s1],mp[s2]);
            addedge(mp[s2],mp[s1]);
        }
        tarjan(1,-1);
        for(i=1;i<=n;i++)//判断图不联通
           if(dfn[i]==-1) break;
        if(i<=n)
        {
            printf("0\n");
            continue;
        }
        printf("%d\n",bum);
        sort(brig,brig+bum,cmp);
        for(int j=0;j<bum;j++)
        {
            i=brig[j];
            if(i&1) i--;
            cout<<hash[E[i].st]<<' '<<hash[E[i].ed]<<endl;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值