从n开始做tarjan,如果一条边不是桥,那么就输出0 0,否则求子树的最大编号。。。
#include <bits/stdc++.h> using namespace std; typedef long long LL; #define mp(x, y) make_pair(x, y) const int maxn = 100005; const int maxm = 200005; struct Edge { int v, next; Edge(int v = 0, int next = 0) : v(v), next(next) {} }E[maxm]; pair<int, int> res[maxn]; int H[maxn], cntE; int dfn[maxn]; int low[maxn]; int mx[maxn]; int n, m, dfs_clock; void addedges(int u, int v) { E[cntE] = Edge(v, H[u]); H[u] = cntE++; E[cntE] = Edge(u, H[v]); H[v] = cntE++; } void init() { cntE = dfs_clock = 0; memset(dfn, 0, sizeof dfn); memset(H, -1, sizeof H); } void tarjan(int u, int fa) { mx[u] = u; dfn[u] = low[u] = ++dfs_clock; for(int e = H[u]; ~e; e = E[e].next) if(E[e].v != fa) { int v = E[e].v; if(!dfn[v]) { tarjan(v, u); low[u] = min(low[u], low[v]); } else low[u] = min(low[u], dfn[v]); } for(int e = H[u]; ~e; e = E[e].next) if(E[e].v != fa) { int v = E[e].v; mx[u] = max(mx[u], mx[v]); if(low[v] > dfn[u]) res[e / 2] = mp(mx[v], mx[v]+1); else res[e / 2] = mp(0, 0); } } void work() { scanf("%d%d", &n, &m); for(int i = 1; i <= m; i++) { int u, v; scanf("%d%d", &u, &v); addedges(u, v); } tarjan(n, n); for(int i = 0; i < m; i++) printf("%d %d\n", res[i].first, res[i].second); } int main() { int _; scanf("%d", &_); while(_--) { init(); work(); } return 0; }