题目其实就是要找出图中所有的割边(桥)。
于是直接 Tarjan 即可。
输出时记得还要排序。
#include <bits/stdc++.h>
using namespace std;
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
const int INF = 0x3f3f3f3f, N = 153, M = 10003;
int n, m;
int tot = 1, head[N], ver[M], nxt[M];
int dfn[N], low[N], tim;
int cnt;
struct Node
{
int u, v;
} a[M];
inline void add(int u, int v)
{
ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
void Tarjan(int u, int fa)
{
dfn[u] = low[u] = ++tim;
for (int i = head[u]; i; i = nxt[i])
{
int v = ver[i];
if (!dfn[v])
{
Tarjan(v, i);
low[u] = min(low[u], low[v]);
if (low[v] > dfn[u])
a[++cnt] = (Node){u, v};
}
else if (i != (fa ^ 1)) low[u] = min(low[u], dfn[v]);
}
}
inline bool cmp(Node x, Node y)
{
if (x.u != y.u) return x.u < y.u;
return x.v < y.v;
}
int main()
{
n = gi(), m = gi();
for (int i = 1; i <= m; i+=1)
{
int u = gi(), v = gi();
add(u, v), add(v, u);
}
for (int i = 1; i <= n; i+=1)
if (!dfn[i]) Tarjan(i, i);
sort(a + 1, a + 1 + cnt, cmp);
for (int i = 1; i <= cnt; i+=1)
printf("%d %d
", a[i].u, a[i].v);
return 0;
}