无向图边双联通分量 tarjan 模板

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int MAXM = 500005;
int n, m;

int fir[MAXN], nxt[MAXM<<1], to[MAXM<<1], cnt = 1;

int low[MAXN], dfn[MAXN], stk[MAXN], scc[MAXN], scccnt, indx, tmr;

inline void Add(int u, int v) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; }

inline void tarjan(int u, int ff)
{
    dfn[u] = low[u] = ++tmr; stk[++indx] = u;
    for(int i = fir[u]; i; i = nxt[i])
        if(!dfn[to[i]]) tarjan(to[i], i), low[u] = min(low[u], low[to[i]]);
        else if((i^1) != ff) low[u] = min(low[u], dfn[to[i]]);
    if(low[u] == dfn[u])
    {
        scccnt++;
        do scc[stk[indx]] = scccnt;
        while(stk[indx--] != u);
    }
}

int main()
{
    int x, y;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i++) scanf("%d%d", &x, &y), Add(x, y), Add(y, x);
    for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i, -1);
}

边双联通分量是存点 点双联通分量

原文地址:https://www.cnblogs.com/Orz-IE/p/12039487.html