lahlahblog喵~

luogu P5180 【模板】支配树

lahlah·2022-02-16 15:30·34 次阅读

luogu P5180 【模板】支配树

https://www.luogu.com.cn/problem/P5180

这篇讲得好:https://www.luogu.com.cn/blog/Wankupi/solution-p5180

code:

Copy
#include<bits/stdc++.h> #define N 400050 using namespace std; vector<int> g[N], gr[N], gt[N]; int dfn[N], id[N], tot, Fa[N], semi[N], idom[N]; void dfs(int u) { dfn[u] = ++ tot; id[tot] = u; for(int v : g[u]) { if(dfn[v]) continue; Fa[v] = u; dfs(v); } } int fa[N], val[N]; int get(int x) { if(fa[x] == x) return x; int y = fa[x]; fa[x] = get(fa[x]); if(dfn[semi[val[y]]] < dfn[semi[val[x]]]) val[x] = val[y]; return fa[x]; } void merge(int x, int y) { x = get(x), y = get(y); fa[y] = x; } int dmin(int x, int y) { return dfn[x] < dfn[y]? x : y; } int n, m, siz[N]; int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) fa[i] = i, siz[i] = 1; for(int i = 1; i <= m; i ++) { int u, v; scanf("%d%d", &u, &v); g[u].push_back(v), gr[v].push_back(u); } dfs(1); dfn[0] = n + 1; for(int i = n; i >= 1; i --) { int u = id[i]; for(int v : gr[u]) { // get semi if(dfn[v] < dfn[u]) semi[u] = dmin(semi[u], v); else { get(v); semi[u] = dmin(semi[u], semi[val[v]]); } } for(int v : gt[u]) { get(v); int x = val[v]; if(dfn[u] == dfn[semi[x]]) idom[v] = u; else idom[v] = x; } val[u] = u; merge(Fa[u], u); gt[semi[u]].push_back(u); } for(int i = 2; i <= n; i ++) { int u = id[i]; if(idom[u] != semi[u]) idom[u] = idom[idom[u]]; } for(int i = n; i > 1; i --) { int u = id[i]; siz[idom[u]] += siz[u]; } for(int i = 1; i <= n; i ++) printf("%d ", siz[i]); return 0; }
posted @   lahlah  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2020-02-16 数学初联杂题乱讲
点击右上角即可分享
微信分享提示