题目

给定一棵 \(n\) 个节点的树,现有有一张完全图,

两点 \(x,y\) 之间的边长为 \(w_x+w_y+dis_{x,y}\),

其中 \(dis\) 表示树上两点的距离。

求完全图的最小生成树。


分析

考虑两两点对都会在重心的位置被统计一次,

而可以在此过程连边,只要找到当前子树\(\min\{w_x+d_x\}\)所对应的\(x\),

一共\(O(n\log_2 n)\)条边,直接跑Kruskal即可


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=200011;
struct node{int y,w,next;}e[N<<1];
struct rec{int x,y; long long w;}b[N<<5];
long long ans,d[N]; bool v[N];
int big[N],siz[N],a[N],SIZ,f[N],cho;
int root,n,m,as[N],tot,et=1,B[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
bool cmp(rec x,rec y){return x.w<y.w;}
inline signed getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
inline signed max(int a,int b){return a>b?a:b;}
inline void dfs(int x,int fa){
siz[x]=1,big[x]=0;
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=fa&&!v[e[i].y]){
dfs(e[i].y,x);
siz[x]+=siz[e[i].y];
big[x]=max(big[x],siz[e[i].y]);
}
big[x]=max(big[x],SIZ-siz[x]);
if (big[x]<=big[root]) root=x;
}
inline void calc(int x,int fa){
B[++tot]=x;
if (a[cho]+d[cho]>a[x]+d[x]) cho=x;
for (rr int i=as[x];i;i=e[i].next)
if (!v[e[i].y]&&e[i].y!=fa)
d[e[i].y]=d[x]+e[i].w,calc(e[i].y,x);
}
inline void dp(int x){
v[x]=1,d[x]=0,cho=B[tot=1]=x;
for (rr int i=as[x];i;i=e[i].next)
if (!v[e[i].y]) d[e[i].y]=d[x]+e[i].w,calc(e[i].y,x);
for (rr int i=1;i<=tot;++i)
b[++m]=(rec){cho,B[i],a[cho]+d[cho]+a[B[i]]+d[B[i]]};
for (rr int i=as[x];i;i=e[i].next)
if (!v[e[i].y]){
big[0]=SIZ=siz[e[i].y];
dfs(e[i].y,root=0),dp(root);
}
}
signed main(){
n=iut();
for (rr int i=1;i<=n;++i) a[i]=iut(),f[i]=i;
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut(),w=iut();
e[++et]=(node){y,w,as[x]},as[x]=et;
e[++et]=(node){x,w,as[y]},as[y]=et;
}
big[0]=SIZ=n,dfs(1,root=0),dfs(root,0),dp(root);
sort(b+1,b+1+m,cmp);
for (rr int i=1;i<=m;++i){
rr int fa=getf(b[i].x),fb=getf(b[i].y);
if (fa!=fb) f[fa]=fb,ans+=b[i].w;
}
return !printf("%lld",ans);
}

#点分治,Kruskal#AT3611 Tree MST的更多相关文章

  1. AT3611 Tree MST 点分治+最小生成树

    正解:点分治+最小生成树 解题报告: 传送门! 然后这题麻油翻译,,,所以这边的建议是先说下题意呢亲 所以题意大概就是说,给一棵n个节点的树,树上每个点都有个权值,然后构造一个完全图,(u,v)之间连 ...

  2. AT3611 Tree MST

    题面 题解 考虑最小化\(dis(x, y)\) 这里需要对一种奇怪的最小生成树算法:Boruvka算法有深刻的理解. 考虑该算法的执行过程,我们可以考虑进行点分治,每次找到离分治重心最近的点,然后将 ...

  3. 【AtCoder3611】Tree MST(点分治,最小生成树)

    [AtCoder3611]Tree MST(点分治,最小生成树) 题面 AtCoder 洛谷 给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x,y\)之间的边长为\(w[x]+w[y]+di ...

  4. [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)

    Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...

  5. 【AT3611】Tree MST

    题目 这个题的输入首先就是一棵树,我们考虑一下点分 我们对于每一个分治重心考虑一下跨过这个分治重心的连边情况 就是把当前分治区域内所有的点向距离分治重心最近的点连边 考虑一下这个算法的正确性,如果我们 ...

  6. HDU 2682 Tree(Kruskal算法求解MST)

    题目: There are N (2<=N<=600) cities,each has a value of happiness,we consider two cities A and ...

  7. 最小生成树 (Minimum Spanning Tree,MST) --- Kruskal算法

    本文链接:http://www.cnblogs.com/Ash-ly/p/5409265.html 引导问题: 假设要在N个城市之间建立通信联络网,则连通N个城市只需要N - 1条线路.这时,自然会考 ...

  8. 【HNOI2010】城市建设(对时间分治 & Kruskal)

    Description \(n\) 个点 \(m\) 条边的带边权无向图.\(q\) 次操作,每次修改一条边的权值. 求每次修改后的最小生成树的边权和. Hint \(1\le n\le 2\time ...

  9. BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )

    做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...

  10. 题解-AtCoder Code-Festival2017 Final-J Tree MST

    Problem \(\mathrm{Code~Festival~2017~Final~J}\) 题意概要:一棵 \(n\) 个节点有点权边权的树.构建一张完全图,对于任意一对点 \((x,y)\),连 ...

随机推荐

  1. win32 - IFileDialog接口的使用

    官方示例: CommonFileDialogModes.cpp 如果我们想要自己创建一个通用的文件对话框,则可以使用IFileOpenDialog接口,代码参考: HRESULT BasicFileO ...

  2. (微服务)服务治理:熔断器介绍以及hystrix-go的使用

    一.什么是熔断器 要理解熔断器,可以先看看电路中使用的保险丝. 保险丝(fuse)也被称为电流保险丝,IEC127 标准将它定义为"熔断体(fuse-link)".保险丝是一种保证 ...

  3. 如何快速使用LayUI MINI框架

    是什么 LayUI MINI是基于LayUI框架开发的一套最简洁.易用的后台框架模板,它已经是一个非常完整的脚手架,有现成的页面模板可以参考甚至是直接使用. 通常来说,如果我们准备开发一套管理系统的W ...

  4. Jetpack Compose(2) —— 入门实践

    一.项目中使用 Jetpack Compose 从此节开始,为方便起见,如无特殊说明,Compose 均指代 Jetpack Compose. 开发工具: Android Studio 1.1 创建支 ...

  5. Kotlin 协程五 —— 在Android 中使用 Kotlin 协程

    目录 一.Android MVVM 结构 二.添加依赖 三.在后台线程中执行 3.1 协程解决了什么问题 3.2 保证主线程安全 3.3 withContext 的性能 四.结构化并发 4.1 追踪协 ...

  6. SSH 客户端

    简介 OpenSSH 的客户端是二进制程序 ssh.它在 Linux/Unix 系统的位置是/usr/local/bin/ssh. Linux 系统一般都自带 ssh,如果没有就需要安装. # Ubu ...

  7. 05-Redis系列之-主从复制配置和优化,fork和aof两大阻塞

    主从复制 原理 一台主服务器配多台从服务器,主服务器宕机后,从服务器挑选一台顶上去. 从服务器同步主服务器的数据,这个同步是单向的,并且从服务器不能设置值,否则会造成数据的混乱 功能 0.故障处理:s ...

  8. sql判断字符串中含中文方法

    基于UTF-8字符集 它是一种多字节字符集,编码为变长编码.那么它的编码范围根据:http://www.iteye.com/topic/977671 作者提供的资料学习,整理出它编码范围如下: u2e ...

  9. 回顾 2023,NebulaGraph 的这一年的变化

    一年又过去了,感谢你和 NebulaGraph 一起又走过一个春夏秋冬.在这 365 天里,我们一起见证了 214 个 commit 带来的 NebulaGraph 3 个中版本的上线,它们分别是 v ...

  10. minio通过docker方式部署

    MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储. 它是与 Amazon S3 云存储服务兼容的 API 官方文档http://docs.minio.org.c ...