割边(输出要排序,贼鸡儿坑)
代码如下:
#include <bits/stdc++.h>
using namespace std;
vector<int> k[10010];
int num[10010], vis[10010], low[10010];
pair<int, int>edge[10010];
int __index;
void Init(int n)
{
__index = 0;
for(int i = 0; i < n; i++)
k[i].clear();
memset(num, 0, sizeof(num));
memset(vis, 0, sizeof(vis));
}
void Cut_edge(int cur, int father, int &sum)
{
vis[cur] = 1;
__index++;
num[cur] = __index;
low[cur] = __index;
int n = k[cur].size();
for(int i = 0; i < n; i++)
{
int cnode = k[cur][i];
if(!num[cnode])
{
Cut_edge(cnode, cur, sum);
low[cur] = min(low[cur], low[cnode]);
if(num[cur] < low[cnode])
{
edge[sum].first = min(cur, cnode);
edge[sum].second = max(cur, cnode);
sum++;
}
}
else if(cnode != father) low[cur] = min(num[cnode], low[cur]);
}
return ;
}
int main ()
{
int t, cnt = 1;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
Init(n);
for(int i = 0; i < n; i++)
{
int u, m, v;
scanf("%d (%d)", &u, &m);
while(m--)
{
scanf("%d", &v);
k[u].push_back(v);
}
}
int ans = 0;
for(int i = 0; i < n; i++)
if(!vis[i])
Cut_edge(i, i, ans);
printf("Case %d:\n", cnt++);
printf("%d critical links\n", ans);
sort(edge, edge+ans);
for(int i = 0; i < ans; i++)
printf("%d - %d\n", edge[i].first, edge[i].second);
}
return 0;
}