//。。刚开始用>=判断割边...一直多一个1-2,看了网上博文发现只是>就可以了。。还有就是割边存储,....不知道我用vector<int>哪错了...样例能过...但是。。WA,,,,然后就用vector<pair<int, int> >了..........但是还是不知道刚开始为啥WA了...
#include<iostream>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std;
const int nMax = 1000+10;
bool cut[nMax];
int Dfn[nMax], low[nMax], parent[nMax];
int vis[nMax];
int root, N, cnt = 0;
vector<pair<int, int> > CutE;
vector<int> G[nMax], CutEdge[nMax];
void addEdge(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
}
void Tarjan(int u, int pa, int indx) {
Dfn[u] = low[u] = indx;
for(int i = 0; i < G[u].size(); ++i) {
int v = G[u][i];
if(Dfn[v]==0) {
parent[v] = u;
Tarjan(v, u, indx+1);
low[u] = min(low[u], low[v]);
if (low[v] > Dfn[u]) {
CutE.push_back(make_pair(min(v, u),max(v,u))),cnt++, CutEdge[u].push_back(v);//割边
}
} else if(pa != v)
low[u] = min(low[u], Dfn[v]);
}
}
void findcut(int dep, int u) {
Dfn[u] = low[u] = dep;
vis[u] = true;
int sum = 0;//以root为根的孩子的数量
for (int i=0; i<G[u].size(); i++) {
int v = G[u][i];
if (!Dfn[v])
//if(!vis[v])
{
if(parent[u] == v) continue;
parent[v] = u;
sum ++;
findcut(dep+1, v);
low[u] = min(low[u], low[v]);//确保low[u]最小
if (low[v] > Dfn[u]) {
CutE.push_back(make_pair(min(v, u),max(v,u))), CutEdge[min(v, u)].push_back(max(v,u));//割边
}
} else if(Dfn[v] < low[u]) { //v的父节点不能用来跟新他的low值
low[u] = Dfn[v];//回溯继续
}
}
}
void init() {
for(int i=0; i<nMax; i++) {
G[i].clear();
CutEdge[i].clear();
}
CutE.clear();
cnt = 0;
memset(vis, false, sizeof(vis));
memset(cut, false, sizeof(cut));
memset(Dfn, 0, sizeof(Dfn));
memset(low, 0, sizeof(low));
memset(parent, -1, sizeof(parent));
}
int main() {
while (~scanf("%d", &N)) {
init();
int u, v;
for (int i = 0; i < N; i++) {
scanf("%d", &u);
int num;
scanf(" (%d) ", &num);
for (int j = 0; j < num; j++) {
scanf("%d", &v);
addEdge(u, v);
}
}
for (int i = 0; i < N; i++)
if (!Dfn[i])
// findcut(1, i);
Tarjan(i, -1, 1);
sort(CutE.begin(), CutE.end());
printf("%d critical links\n", (int)CutE.size());
for (int i = 0; i < CutE.size(); i++)
printf("%d - %d\n", CutE[i].first, CutE[i].second);
printf("\n");
/*
//WA
printf("%d critical links\n", cnt);
for (int i = 0; i < nMax; i++) {
sort(CutEdge[i].begin(), CutEdge.end());
for(int j=0; j<CutEdge[i].size(); j++) {
printf("%d - %d\n", i, CutEdge[i][j]);
}
}
printf("\n");
*/
}
return 0;
}