最小树形图
最小树形图¶
有向图上的最小生成树(Minimum Directed Spanning Tree)称为最小树形图。
常用的算法是朱刘算法(也称 Edmonds 算法),可以在 O(nm) 时间内解决最小树形图问题。
流程¶
- 对于每个点,选择它入度最小的那条边
- 如果没有环,算法终止;否则进行缩环并更新其他点到环的距离。
代码¶
bool solve() {
ans = 0;
int u, v, root = 0;
for (;;) {
f(i, 0, n) in[i] = 1e100;
f(i, 0, m) {
u = e[i].s;
v = e[i].t;
if (u != v && e[i].w < in[v]) {
in[v] = e[i].w;
pre[v] = u;
}
}
f(i, 0, m) if (i != root && in[i] > 1e50) return 0;
int tn = 0;
memset(id, -1, sizeof id);
memset(vis, -1, sizeof vis);
in[root] = 0;
f(i, 0, n) {
ans += in[i];
v = i;
while (vis[v] != i && id[v] == -1 && v != root) {
vis[v] = i;
v = pre[v];
}
if (v != root && id[v] == -1) {
for (int u = pre[v]; u != v; u = pre[u]) id[u] = tn;
id[v] = tn++;
}
}
if (tn == 0) break;
f(i, 0, n) if (id[i] == -1) id[i] = tn++;
f(i, 0, m) {
u = e[i].s;
v = e[i].t;
e[i].s = id[u];
e[i].t = id[v];
if (e[i].s != e[i].t) e[i].w -= in[v];
}
n = tn;
root = id[root];
}
return ans;
}
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:OI-wiki
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用