最小树形图
最小树形图¶
有向图上的最小生成树(Minimum Directed Spanning Tree)称为最小树形图。
常用的算法是朱刘算法(也称 Edmonds 算法),可以在 O(nm) 时间内解决最小树形图问题。
流程¶
- 对于每个点,选择它入度最小的那条边
- 如果没有环,算法终止;否则进行缩环并更新其他点到环的距离。
代码¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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 协议之条款下提供,附加条款亦可能应用