#点分治,Kruskal#AT3611 Tree MST
题目
给定一棵 \(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的更多相关文章
- AT3611 Tree MST 点分治+最小生成树
正解:点分治+最小生成树 解题报告: 传送门! 然后这题麻油翻译,,,所以这边的建议是先说下题意呢亲 所以题意大概就是说,给一棵n个节点的树,树上每个点都有个权值,然后构造一个完全图,(u,v)之间连 ...
- AT3611 Tree MST
题面 题解 考虑最小化\(dis(x, y)\) 这里需要对一种奇怪的最小生成树算法:Boruvka算法有深刻的理解. 考虑该算法的执行过程,我们可以考虑进行点分治,每次找到离分治重心最近的点,然后将 ...
- 【AtCoder3611】Tree MST(点分治,最小生成树)
[AtCoder3611]Tree MST(点分治,最小生成树) 题面 AtCoder 洛谷 给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x,y\)之间的边长为\(w[x]+w[y]+di ...
- [bzoj1016][JSOI2008]最小生成树计数 (Kruskal + Matrix Tree 定理)
Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的 ...
- 【AT3611】Tree MST
题目 这个题的输入首先就是一棵树,我们考虑一下点分 我们对于每一个分治重心考虑一下跨过这个分治重心的连边情况 就是把当前分治区域内所有的点向距离分治重心最近的点连边 考虑一下这个算法的正确性,如果我们 ...
- HDU 2682 Tree(Kruskal算法求解MST)
题目: There are N (2<=N<=600) cities,each has a value of happiness,we consider two cities A and ...
- 最小生成树 (Minimum Spanning Tree,MST) --- Kruskal算法
本文链接:http://www.cnblogs.com/Ash-ly/p/5409265.html 引导问题: 假设要在N个城市之间建立通信联络网,则连通N个城市只需要N - 1条线路.这时,自然会考 ...
- 【HNOI2010】城市建设(对时间分治 & Kruskal)
Description \(n\) 个点 \(m\) 条边的带边权无向图.\(q\) 次操作,每次修改一条边的权值. 求每次修改后的最小生成树的边权和. Hint \(1\le n\le 2\time ...
- BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
做一次MST, 枚举不在最小生成树上的每一条边(u,v), 然后加上这条边, 删掉(u,v)上的最大边(或严格次大边), 更新答案. 树链剖分然后ST维护最大值和严格次大值..倍增也是可以的... - ...
- 题解-AtCoder Code-Festival2017 Final-J Tree MST
Problem \(\mathrm{Code~Festival~2017~Final~J}\) 题意概要:一棵 \(n\) 个节点有点权边权的树.构建一张完全图,对于任意一对点 \((x,y)\),连 ...
随机推荐
- [攻防世界][Web]ics-06
打开靶机对应的url,展开是一个网站的样子,其实啥也么有 所有tab都点一遍,发现只有报表中心有内容,url为 http://61.147.171.105:49797/index.php?id=1 猜 ...
- extra用法
做子查询时,有些orm语句满足不了的时候使用 select参数 ## select age,(age > 18) as is_adult from myapp_person; Person.ob ...
- Sourcetree 如何关联自己的gitlab仓库
现在有些企业自己搭建了gitlab服务器,通过sourcetree从企业服务器拉取代码的时候会提示认证失败.今天搞了大半天才搞懂,给我自己做个笔记. 添加账户 托管服务商 选择 GitLab CE 托 ...
- 记一次酣畅淋漓的 K8s Ingress 排错过程(302,404,503,...)
故事开始 第 1 关:[流量重定向到 /] 第 2 关:[应用返回 302,重定向到 /,引入 503 错误] 第 3 关:[静态资源访问遇到 503 问题] 第 4 关:[静态资源访问遇到 403 ...
- ThreadLocal原理解析
ThreadLocal源码分析 /* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * ...
- 【Azure 应用服务】App Service For Linux 中安装paping, 用于验证从App Service向外请求的网络连通性
问题描述 App Service For Linux 中安装paping的操作步骤 解决步骤 1) 登录App Service的Kudu站点,点击Bash 2)使用命令下载paping压缩文件:#wg ...
- MVVM框架模式
MVC框架模式 MVP框架模式 MVVM框架模式 MVVM模式即: 1.Model:数据层.网络数据操作,file文件操作,本地数据库操作: 2.View:视图层.布局加载,ui交互. 3.ViewM ...
- opencv库图像基础4绘图-python
opencv库图像基础4绘图-python 1.绘画线条和简单图形 创建颜色字典和一个画布 import cv2 import numpy as np import matplotlib.pyplot ...
- vscode 花括号 突出连接线 bracket 两个设置点 (括号标识符)
vscode 花括号 突出连接线 bracket 两个设置点 外观 设置 设置里面搜索 bracket Editor - Guides: Highlight Active Bracket Pair E ...
- linux下命令行打开文件夹窗口
方法一: 使用自带的命令:nautilus . 打开当前文件夹 nautilus . 打开指定路径文件夹 nautilus ddd/ccc/ 方法二:xdg-open xdg-open 命令相当于在 ...