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;
}

猜你喜欢

转载自www.cnblogs.com/quanjun/p/12908016.html
今日推荐