支配树

模板

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 200010, M = 300010;
int n, m, ans[N], head[N][3], nex[N + M * 2], ver[N + M * 2], tot, dfn[N], ord[N], cnt, fth[N], idom[N], semi[N], uni[N], mn[N];
inline void add (int x, int y, int id) {
    ver[++ tot] = y;
    nex[tot] = head[x][id];
    head[x][id] = tot;
}
void tarjan (int x) {
    dfn[x] = ++ cnt;
    ord[dfn[x]] = x;
    for (int i = head[x][0]; i; i = nex[i]) {
        int y = ver[i];
        if (!dfn[y]) {
            fth[y] = x;
            tarjan(y);
        }
    }
}
inline int uni_query (int x) {
    if (x == uni[x]) return x;
    int tmp = uni_query(uni[x]);
    if (dfn[semi[mn[x]]] > dfn[semi[mn[uni[x]]]]) mn[x] = mn[uni[x]];
    return uni[x] = tmp;
}
void lengauerTarjan (int s) {
    tarjan(s);
    for (int i = 1; i <= n; i ++) semi[i] = uni[i] = mn[i] = i;
    for (int id = cnt; id >= 2; id --) {
        int x = ord[id];
        for (int i = head[x][1]; i; i = nex[i]) {
            int y = ver[i];
            if (!dfn[y]) continue;
            uni_query(y);
            if (dfn[semi[x]] > dfn[semi[mn[y]]]) semi[x] = semi[mn[y]];
        }
        uni[x] = fth[x];
        add(semi[x], x, 2);
        x = fth[x];
        for (int i = head[x][2]; i; i = nex[i]) {
            int y = ver[i];
            uni_query(y);
            idom[y] = (x == semi[mn[y]] ? x : mn[y]);
        }
        head[x][2] = 0;
    }
    for (int i = 2; i <= cnt; i ++) {
        int x = ord[i];
        if (idom[x] != semi[x])
            idom[x] = idom[idom[x]];
    }
}
int main () {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i ++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y, 0);
        add(y, x, 1);
    }
    lengauerTarjan(1);
    for (int i = cnt; i >= 2; i --) {
        ans[ord[i]] ++;
        ans[idom[ord[i]]] += ans[ord[i]];
    }
    ans[1] ++;
    for (int i = 1; i <= n; i ++) printf("%d ", ans[i]);
    return 0;
}
posted @   duoluoluo  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示