BZOJ P3732 Network(Kruskal重构树)

Network

题目描述:

N 个点的无向图 (1N15000), 记为: 1N
图中有 M 条边 (1M30000) ,第 i 条边的长度记为 di(1di109) ,现在有 K 个询问 (1K20000) .每次询问查询从 AB 的所有路径中最长边的最小值

思路:

首先引入 Kruskal 重构树的概念。 Kruskal 重构树是基于最小生成树上建立的一个新树,构造的原理是将最小生成树的边权转变为该边所连的两个节点的公共祖先的点权。具体如下图。
img
img
那么最后的 Kruskal 重构树就是一个 2n1 个节点, 2n2 条边的树。
同时 Kruskal 重构树具有一个很重要的性质:原图中两个点间所有路径上的边最大权值的最小值 = 最小生成树上两点简单路径的边最大权值 = Kruskal 重构树上两点 LCA 的点权。如果是求最小权值的最大值,就是最大生成树的基础上建重构树。
那么这个题就变成了 Kruskal 重构树的模板题

重构最小生成树

struct node { int u, v, w; bool operator< (const node& lhs) const { return w < lhs.w; } }edge[N]; int n, m, k, nn; int h[N], idx, val[N], e[N], ne[N]; void add(int a, int b) { e[++idx] = b, ne[idx] = h[a], h[a] = idx; } int fa[N]; int find(int x) { return x == fa[x] ? fa[x] : fa[x] = find(fa[x]); } void kruskal() { for (int i = 1; i < N; i++) fa[i] = i; std::sort(edge + 1, edge + 1 + m); for (int i = 1; i <= m; i++) { int u = edge[i].u, v = edge[i].v, w = edge[i].w; if (find(u) == find(v)) continue; u = find(u), v = find(v); val[++n] = w; fa[n] = fa[u] = fa[v] = n; add(n, u), add(n, v); } }

树剖求 LCA

int dep[N], siz[N], par[N], son[N], top[N]; void dfs1(int u, int pa) { par[u] = pa, siz[u] = 1, dep[u] = dep[pa] + 1; for (int i = h[u]; i; i = ne[i]) { int v = e[i]; if (v == pa) continue; dfs1(v, u); siz[u] += siz[v]; if (siz[v] > siz[son[u]]) son[u] = v; } } void dfs2(int u, int tp) { top[u] = tp; if (!son[u]) return ; dfs2(son[u], tp); for (int i = h[u]; i; i = ne[i]) { int v = e[i]; if (v == par[u] || v == son[u]) continue; dfs2(v, v); } } int lca(int u, int v) { while(top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) std::swap(u, v); u = par[top[u]]; } return dep[u] < dep[v] ? u : v; }

主函数

signed main() { scanf("%d%d%d", &nn, &m, &k); n = nn; for (int i = 1; i <= m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); edge[i] = {u, v, w}; } kruskal(); dfs1(n, 0); dfs2(n, n); for (int i = 0; i < k; i++) { int a, b; scanf("%d%d", &a, &b); printf("%d\n", val[lca(a, b)]); } return 0 ^ 0; }

__EOF__

本文作者HoneyGrey
本文链接https://www.cnblogs.com/Haven-/p/16855533.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   浅渊  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示