#include<iostream>
#include<queue>
#include<list>
#include<vector>
#include<cstring>
#include<set>
#include<stack>
#include<map>
#include<cmath>
#include<algorithm>
#include<string>
#include<stdio.h>
using namespace std;
typedef long long ll;
#define MS(x,i) memset(x,i,sizeof(x))
#define rep(i,s,e) for(int i=s; i<=e; i++)
#define sc(a) scanf("%d",&a)
#define scl(a) scanf("%lld",&a)
#define sc2(a,b) scanf("%d %d", &a, &b)
#define debug printf("debug......\n");
#define pfd(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
const double eps=1e-8;
const double PI = acos(-1.0);
const int inf = 0x3f3f3f3f;
const ll INF = 0x7fffffff;
const int maxn = 1e6+10;
int dx[4] = {0, 0, 1, -1};
int dy[4]  = {1, -1, 0 , 0};
int n,m;
int low[maxn];//顶点的low值
int ids[maxn];//顶点的dfs次序
bool vis[maxn];//访问标记
int id;//dfs次序
vector<int> G[maxn];//存图

struct edge{
    int u,v;
    edge(int a, int b){u = a; v = b;}
    bool operator < (const edge x) const{
        if(u == x.u) return v < x.v;
        return u < x.u;
    }
};
vector<edge> bridge;//存答案
//
void dfs(int u, int pre){
    vis[u] = 1;
    low[u] = ids[u] = ++id;
    for(int i=0; i<G[u].size(); i++){
        int v = G[u][i];
        if(v == pre) continue;
        if(!vis[v]){
            dfs(v , u);
            low[u] = min(low[u] , low[v]);
            //桥存在定理 
            if(ids[u] < low[v]){
                int uu = u, vv = v;
                //根据题意 这里需要把u调成小的
                if(uu > vv) swap(uu , vv);
                bridge.push_back(edge(uu,vv));
            }
        }
        else{
            low[u] = min(low[u] , ids[v]);
        }
    }
}

void findBrige(){
    id = 0;
    MS(low , 0);
    MS(vis , 0);
    bridge.clear();
    
    rep(i,0,n-1){
        if(!vis[i]) dfs(i, -1);
    }
}



int main(){
    while(sc(n)!=EOF){
        //if(n == 0) break;
        rep(i,0,n-1)  G[i].clear();
        rep(i,0,n-1){
            int u,k,v;
            scanf("%d (%d)",&u, &k);
            while(k--){
                sc(v);
                G[u].push_back(v);
            }
        }
        findBrige();
        sort(bridge.begin(),bridge.end());
        printf("%d critical links\n",bridge.size());
        for(int i=0; i<bridge.size(); i++){
            printf("%d - %d\n",bridge[i].u,bridge[i].v);
        }
        printf("\n");
    }
    return 0;
}
上一篇:ros的公网IP配置在vlan接口上,而这个vlan又在桥接上的做法


下一篇:HDU-5215 Cycle 无向图判奇环偶环