Tarjan求无向图割边
示例代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010, maxm = 200020;
struct Edge {
int v, nxt;
Edge() {};
Edge(int _v, int _nxt) { v = _v; nxt = _nxt; }
} edge[maxm];
int n, m, head[maxn], ecnt;
void init() {
ecnt = 0;
memset(head, -1, sizeof(int)*(n+1));
}
void addedge(int u, int v) {
edge[ecnt] = Edge(v, head[u]); head[u] = ecnt ++;
edge[ecnt] = Edge(u, head[v]); head[v] = ecnt ++;
}
int dfn[maxn], low[maxn], num;
bool bridge[maxm];
void tarjan(int u, int in_edge) {
dfn[u] = low[u] = ++ num;
for (int i = head[u]; i != -1; i = edge[i].nxt) {
int v = edge[i].v;
if (!dfn[v]) {
tarjan(v, i);
low[u] = min(low[u], low[v]);
if (dfn[u] < low[v])
bridge[i] = bridge[i^1] = true;
}
else if (i != (in_edge^1))
low[u] = min(low[u], dfn[v]);
}
}
void test() {
puts("[test]");
for (int i = 1; i <= n; i ++)
printf("dfn[%d] = %d, low[%d] = %d\n", i, dfn[i], i, low[i]);
}
int main() {
cin >> n >> m;
init();
for (int i = 0; i < m; i ++) {
int u, v, w;
cin >> u >> v;
addedge(u, v);
}
for (int i = 1; i <= n; i ++) if (!dfn[i]) tarjan(i, -1);
bool flag = false;
for (int i = 0; i < m; i ++) {
if (bridge[i*2]) {
flag = true;
cout << i+1 << endl;
}
}
if (!flag) puts("no");
// test();
return 0;
}