想一想其实写这种题最应该%的是tarjan。
题意+思路: 求割边的模板题,有重边的绝对不是割边,然而这题应该没有有重边的情况。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <set>
using namespace std;
const int maxe = 1e4;
const int maxn = 2e2;
struct node
{
int f,to,next;
int isb;
node(){}
node(int d,int a,int b,int c){f = d; to = a; next = b;isb = c;}
}edge[maxe << 2];
set<pair<int,int> > out;
int edgenum = 0,tot = 0,ansnum = 0;
int h[maxn], dfn[maxn], low[maxn];
int n;
void init()
{
for(int i = 1; i <= n ; i++)
h[i] = -1, dfn[i] = low[i] = 0;
edgenum = tot = ansnum = 0;
out.clear();
}
bool cmp(node a,node b)
{
return a.f < b.f;
}
void add(int u,int v)
{
edge[edgenum] = node(u,v,h[u],0);
h[u] = edgenum ++;
}
int tarjan(int u,int fa)
{
dfn[u] = low[u] = ++tot;
for(int i = h[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
//cout << "u v " << u << " " << v << endl;
if(!dfn[v])
{
tarjan(v,u);
low[u] = min(low[u],low[v]);
if(dfn[u] < low[v])
{
int a = u, b = v;
if(u > v) swap(a,b);
out.insert(pair<int,int>(a,b));
}
}
else if(dfn[v] < dfn[u] && v != fa)
low[u] = min(low[u],dfn[v]);
}
return 0;
}
char strin[1500];
int main()
{
//freopen("D://in.txt","r", stdin);
int flag = 0;
while(~scanf("%d",&n))
{
init();
for(int i = 0; i < n ; i++)
{
int u,v,vnum;
scanf("%d (%d)",&u,&vnum); u++;
for(int j = 0; j < vnum; j++)
{
scanf("%d",&v);
v++;
add(u,v);
}
}
for(int i = 1; i <= n ; i++)
if(!dfn[i]) tarjan(i,-1);
printf("%d critical links\n",out.size());
for(auto it : out)
printf("%d - %d\n",it.first - 1, it.second - 1 );
printf("\n");
}
return 0;
}