本题idea版权来自CSDN博客Steve_Junior的医院设置2

并没有什么用的链接

题目背景

\(A\)国的国情十分独特。它总共有\(n\)个城市,由\(n-1\)条道路连接。国内的城市当然是连通的。

时隔多年,全国会议再次召开。全国人民欢欣雀跃,期待会议后国家发展揭开新篇章。然而,会议筹备组此时却在为会议选址问题头痛不已。

题目描述

为了响应“保护环境”的国策,中央决定不再将首都作为固定会址,而是先计算出全国每个城市参会代表人数\(p_i\),若将城市u作为会址,定义城市v的出行开销为\(C_{v}=p_{v}*dis_{u,v}\)。会议筹备组的任务是选定一个城市\(u\),使出行总开销\(\sum_{i=1}^{n}C_{i}\)最小。

输入格式

第一行一个数字\(n\),表示城市总数。

第二行\(n\)个数字,表示每个城市参会代表人数。

第三行至第\(n+2\)行,每行三个数字\(u,v,w\),表示一条权值为\(w\)的连接城市\(u\)与城市\(v\)的道路。

输出格式

一个数字,表示最小出行总开销。

数据范围

对于30%的数据,\(n\leq 200\)。

对于50%的数据,\(n\leq 1500\)。

对于100%的数据,\(n\leq 5\times 10^{5},1\leq w\leq 10^{4}\)。

题解

30分做法

floyd暴力求出任意点对之间的距离,枚举每个城市作为会址,计算出总开销之后取最小值。大概5分钟就可以写完。复杂度为\(O(n^3)\)。这也是对拍时std采用的做法。

50分做法

将暴力求任意点对之间距离的算法改为\(n\)次堆优化dijkstra算法就可以通过。或者也可以采用一遍DFS后暴力查询\(O(n^2)\)次LCA的做法。其实是为了强行凑部分分才这样设计的

100分做法

这个做法十分玄妙其实只是自己一开始nc了而已……。

下面到了精彩的猜结论时间

理性分析画图发现会址其实就是树的带权重心,与边权无关。


贴一个来自学弟的证明:

考虑这棵树中的某一条边\((u,v)\),判断\(u\)和\(v\)哪个作为会址更优。可以看成城市\(u\)一侧的代表已经全部转移至城市\(u\),城市\(v\)也是如此。此时不难发现,将会址设在两个城市中此时所处代表更多的那个城市,总开销是最小的。因此,每次会址向更优的方向调整时就会不断向树的带权重心靠近,最后带权重心就是会址。


带权重心的求法其实和不带权的没有什么区别。将节点数改成代表数就可以了。

找到带权重心之后,接下来的任务变成了快速求出总开销。这个可以用简单的树形DP实现。

以重心为全树的根节点,设计状态\(f_i\)为将以\(i\)为根节点的子树中所有节点转移至节点\(i\)的总开销,最后\(f_{root}\)就是答案。转移时,记\(v\rightarrow u\)为v是u的子节点,则\(f_{u}=\sum\limits_{v\rightarrow u}(f_{v}+size_{v}\cdot w_{u,v})\)。可以看作将已经转移至\(v\)的所有代表经过边\((u,v)\)转移至\(u\)。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10,maxm=2e5+10,inf=0x7fffffff;
int heade[maxn],dw[maxn],ev[maxm],ew[maxm],nexte[maxm];
int size[maxn],f[maxn],cost[maxn];
int n,tot=0,root,sum=0;
void add_edge(int u,int v,int w){ev[++tot]=v;ew[tot]=w;nexte[tot]=heade[u];heade[u]=tot;}
void getroot(int ui,int fa)
{
int i,vi;
size[ui]=dw[ui];f[ui]=0;
for(i=heade[ui];~i;i=nexte[i])
{
vi=ev[i];if(vi==fa){continue;}
getroot(vi,ui);size[ui]+=size[vi];
f[ui]=max(f[ui],size[vi]);
}
f[ui]=max(f[ui],sum-size[ui]);
if(f[ui]<f[root]){root=ui;}
}
void dfs(int ui,int fa)
{
int i,vi,wi;
size[ui]=dw[ui];cost[ui]=0;
for(i=heade[ui];~i;i=nexte[i])
{
vi=ev[i];wi=ew[i];if(vi==fa){continue;}
dfs(vi,ui);
size[ui]+=size[vi];
cost[ui]+=cost[vi]+size[vi]*wi;
}
}
int main()
{
int i,j,u,v,w;
//freopen("data.in","r",stdin);
//freopen("test.out","w",stdout);
cin>>n;
memset(heade,-1,sizeof(heade));
for(i=1;i<=n;i++){scanf("%d",&dw[i]);sum+=dw[i];}
for(i=1;i<n;i++){scanf("%d%d%d",&u,&v,&w);add_edge(u,v,w);add_edge(v,u,w);}
root=0;f[0]=inf;getroot(1,0);
dfs(root,0);
cout<<cost[root];
return 0;
}

Luogu T16048 会议选址的更多相关文章

  1. [Luogu 1395] 会议

    题目 Description 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那 ...

  2. luogu P1395 会议

    题目描述 有一个村庄居住着n个村民,有n-1条路径使得这n个村民的家联通,每条路径的长度都为1.现在村长希望在某个村民家中召开一场会议,村长希望所有村民到会议地点的距离之和最小,那么村长应该要把会议地 ...

  3. luogu P1359会议

    //以一号节点为根节点,求出所有节点到根结点的距离,以及所有点的子节点的个数 //然后计算根据已知信息计算所有节点到当前结点的距离 //然后扫描n个点,O(n)求解 #include<bits/ ...

  4. 【题解】Luogu P2605 [ZJOI2010]基站选址

    原题传送门:P2604 [ZJOI2010]基站选址 看一眼题目,变知道这题一定是dp 设f[i][j]表示在第i个村庄修建第j个基站且不考虑i+1~n个村庄的最小费用 可以得出f[i][j] = M ...

  5. [Luogu] 无线网络发射器选址

    https://www.luogu.org/problemnew/show/P2038 二维前缀和 #include <iostream> #include <cstdio> ...

  6. luogu P2605 [ZJOI2010]基站选址

    luogu 先考虑朴素dp,设\(f_{i,j}\)表示在第\(i\)个村庄放了基站,一共放了\(j\)次,且只考虑前面村庄影响的答案.这里可以把\(j\)放在外面枚举,然后从\(f_{k,j-1}( ...

  7. luogu P2605 [ZJOI2010]基站选址 线段树优化dp

    LINK:基站选址 md气死我了l达成1结果一直调 显然一个点只建立一个基站 然后可以从左到右进行dp. \(f_{i,j}\)表示强制在i处建立第j个基站的最小值. 暴力枚举转移 复杂度\(n\cd ...

  8. [Luogu P3626] [APIO2009] 会议中心

    题面 传送门:https://www.luogu.org/problemnew/show/P3626 Solution 如果题目只要求求出第一问,那这题显然就是大水题. 但是加上第二问的话...... ...

  9. luogu P4360 [CEOI2004]锯木厂选址

    斜率优化dp板子题[迫真] 这里从下往上标记\(1-n\)号点 记\(a_i\)表示前缀\(i\)里面树木的总重量,\(l_i\)表示\(i\)到最下面的距离,\(s_i\)表示\(1\)到\(i-1 ...

随机推荐

  1. 【Java基础】基本语法-变量与运算符

    基本语法-变量与运算符 关键字和保留字 关键字定义:被 Java 语言赋予了特殊含义,用做专门用途的字符串(单词). 关键字特点:关键字中所有字母都为小写. 用于定义数据类型:class.interf ...

  2. #2020征文-开发板# 用鸿蒙开发AI应用(五)HDF 驱动补光灯

    目录: 前言 硬件准备 HDF 驱动开发 总结 前言上一篇,我们在鸿蒙上运行了第一个程序,这一篇我们来编写一个驱动开启摄像头的红外补光灯,顺便熟悉一下鸿蒙上的 HDF 驱动开发. 硬件准备先查一下原理 ...

  3. MyBatis 查询的时候属性名和字段名不一致的问题

    目录 问题 解决方案:resultMap 问题 当我们数据库中的字段和实体类中的字段不一致的时候,查询会出问题 数据库字段是 pwd id name pwd 1 张三 123456 2 李四 1234 ...

  4. sa-token 之权限验证

    权限验证 核心思想 所谓权限验证,验证的核心就是当前账号是否拥有一个权限码 有:就让你通过.没有:那么禁止访问 再往底了说,就是每个账号都会拥有一个权限码集合,我来验证这个集合中是否包括我需要检测的那 ...

  5. python sqlite3增加表字段

    给sqlite3表格增加新字段,要注意大小写,要不然不成功. 一开始这样写,不成功! 后面规范写,按大小写严格规范写! 成功了!现在查看新增加的字段commit: 仔细看,这下全部小写,括表名称.co ...

  6. C语言流程图画法(C语言学习笔记)

    常用符号及其含义 图片来自百度文库 https://wenku.baidu.com/view/beb410dea216147916112853.html 常用结构 N-S图

  7. [工作札记]03: 微软Winform窗体中ListView、DataGridView等控件的Bug,会导致程序编译失败,影响范围:到最新的.net4.7.2都有

    工作中,我们发现了微软.net WinForm的一个Bug,会导致窗体设计器自动生成的代码失效,这个Bug从.net4.5到最新的.net4.7.2都存在,一直没有解决.最初是我在教学工作中发现的,后 ...

  8. 前端知识(二)01-NPM包管理器-谷粒学院

    目录 一.简介 二.使用npm管理项目 1.项目初始化 2.修改npm镜像 3.npm install命令的使用 4.其它命令 一.简介 什么是NPM NPM全称Node Package Manage ...

  9. 事件循环Event loop到底是什么

    摘要:本文通过结合官方文档MDN和其他博客深入解析浏览器的事件循环机制,而NodeJS有另一套事件循环机制,不在本文讨论范围中.process.nextTick和setImmediate是NodeJS ...

  10. elasticsearch从开始到永久

    0.学习目标 独立安装Elasticsearch 会使用Rest的API操作索引 会使用Rest的API查询数据 会使用Rest的API聚合数据 掌握Spring Data Elasticsearch ...