UVA796(61/600)

套上双联通分量的板子
标记一个爹
然后map记一下
舒服

#include<bits/stdc++.h>
using namespace std;
vector<int>tu[101];
int liantong[10100], dfn[10100], low[10100], clj = 0, jc = 0;
stack<int>zz;
map<int,int>mp[10100];
void tarjan(int xianzai,int ba)
{
    dfn[xianzai] = low[xianzai] = ++clj;
    zz.push(xianzai);
    for (int a = 0;a<tu[xianzai].size();a++)
    {
        int dd = tu[xianzai][a];
        if (!dfn[dd])
        {
            tarjan(dd,xianzai);
            low[xianzai] = min(low[xianzai], low[dd]);
        }
        else if(dd!=ba)
        {
            if (!liantong[dd])low[xianzai] = min(low[xianzai], low[dd]);
        }
    }
    if (low[xianzai] == dfn[xianzai])
    {
        jc++;
        for (;;)
        {
            int ww = zz.top();
            zz.pop();
            liantong[ww] = jc;
            if (ww == xianzai)break;
        }
    }
}
struct p
{
    int z,y;
    bool operator < (const p&a)const{
    if(z==a.z)return y<a.y;
    return z<a.z;
    }
};
p dan[1000000];
int main()
{
    int n;
    while(cin>>n)
    {
        while(!zz.empty())zz.pop();
        for(int a=0;a<n;a++)tu[a].clear();
        memset(liantong,0,sizeof(liantong));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        clj=0,jc=0;
        memset(dan,0,sizeof(dan));
        for(int a=1;a<=n;a++)
        {
            int q,w,e;
            scanf("%d (%d)",&q,&w);
            for(int b=1;b<=w;b++)
            {
                scanf("%d",&e);
                tu[q].push_back(e);
            }
        }
        for(int a=0;a<n;a++)
        {
            if(dfn[a])continue;
            tarjan(a,-1);
        }
        for(int a=0;a<=n;a++)mp[a].clear();
        int we=0;
        for(int a=0;a<n;a++)
        {
            for(int b=0;b<tu[a].size();b++)
            {
                int yy=tu[a][b];
                if(liantong[a]==liantong[yy])continue;
                if(mp[liantong[a]][liantong[yy]])continue;
                if(mp[liantong[yy]][liantong[a]])continue;
                mp[liantong[yy]][liantong[a]]=mp[liantong[a]][liantong[yy]]=1;
                dan[++we]={a,yy};
            }
        }
        printf("%d critical links\n",we);
        for(int a=1;a<=we;a++)
        {
            printf("%d - %d\n",dan[a].z,dan[a].y);
        }
        printf("\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值