一. 题面:点这里

二. 思路:

首先有一个比较常用的 trick 就是对于任意一颗带权树,对于题目中所求的两点对之间的距离和有如下公式:

\[Sum_{dis}=\sum_{e\in E}w(e)\times size_v\times(n-size_v)
\]

这个公式应当是容易理解的,那么最后的贡献就可以这么算,但是现在有一个连边的问题。这和最优化问题有关,可以 dp 吗?好像不太现实,那我们考虑贪心。一步步来,首先你肯定会有一个疑问就是如果要连边,应当连到这个连通块的哪一个点呢。因为连通块本身的点对之间距离是确定的,考虑其他连通块连过来时造成的贡献,显然我们应当让这个连接点到这个连通块其他部分的距离和最小(很好证明)。关于距离和最小这个问题是经典的,可以其中一个解法是可以考虑换根dp 。解决这个问题之后,我们就要考虑我们分别连接哪些联通块是最优的呢。让我们回到算贡献的式子,那么我们应当是希望这个图是菊花图(假设我们把所有连通块内部的点缩成一个点之后),这样可以最小化每一个形如 \(x(n-x)\) 的乘积式。问题是菊花图的中心是什么呢。我们猜想是连通块大小最大的那一个,证明考虑反证法,假设调换最大块和某一块的值,一定不会使答案变小,手搓一个二次函数图像之后就会发现这个问题等价于证明:任意一个正整数 \(t\) 表示不是最大块的大小都有:

\[t\leq n-\max\{size\}
\]

那么这是显然成立的(请读者自行思考,这是简单的。)

所以最后只需要以最大块向外连边即可,至于连边的顺序,考虑将边权大的连向乘积贡献小的连通块即可。

三. Code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#define ll __int128
inline int read() {
int x=0,f=1;char ch=getchar();
while(ch > '9' || ch < '0'){if(ch == '-'){f = -1;}ch = getchar();}
while(ch >= '0'&&ch <= '9'){x = x * 10 + ch - 48; ch = getchar();}
return x * f;
} inline void write(ll x)
{
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + 48);
return;
}
const int N = 1e6 + 5,MOD = 1e9 + 7;
int siz[N],a[N];
std::vector<std::pair<int,int> > G[N]; ll dfs(int u,int fa)
{
siz[u] = 1;
ll res = 0;
for(auto now : G[u])
{
int v = now.first,w = now.second;
if(v == fa) continue;
res += dfs(v,u) + 1ll * siz[v] * w;
siz[u] += siz[v];
}
return res;
} ll tmp_res = 0,mn = 0;
void chgrt_dp(int u,int fa,ll mn_now,int now_siz)
{
mn = std::min(mn,mn_now);
tmp_res += mn_now;
for(auto now : G[u])
{
int v = now.first,w = now.second;
if(v == fa) continue;
chgrt_dp(v,u,mn_now + 1ll * (now_siz - siz[v]) * w - 1ll * siz[v] * w,now_siz);
}
} bool cmp(int a,int b){return a > b;}
int main()
{
int n,m;
n = read(),m = read();
for(int i = 1;i <= m;++i)
{
int u,v,w;
u = read(),v = read(),w = read();
G[u].push_back({v,w});
G[v].push_back({u,w});
} for(int i = 1;i <= n - m - 1;++i) a[i] = read();
std::sort(a + 1,a + n - m);
std::vector<int> p;
ll ans = 0;
for(int i = 1;i <= n;++i)
{
if(!siz[i])
{
mn = dfs(i,0);
tmp_res = 0;
chgrt_dp(i,0,mn,siz[i]);
ans += tmp_res / 2 + 1ll * (n - siz[i]) * mn;
p.push_back(siz[i]);
}
}
std::sort(p.begin(),p.end(),cmp); for(int i = 1;i <= n - m - 1;++i) ans += 1ll * (n - p[i]) * p[i] * a[i];
write(ans % MOD);
return 0;
}

P12007 【MX-X10-T3】[LSOT-4] 全国联赛?题解的更多相关文章

  1. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

  2. 树网的核 2007年NOIP全国联赛提高组(floyed)

    树网的核 2007年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description [问题描述]设 T= ...

  3. 观光公交 2011年NOIP全国联赛提高组(贪心,递推)

    观光公交 2011年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold       题目描述 Description 风景迷人的小城 Y 市 ...

  4. Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组

    1069 关押罪犯 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description S 城现有两座监狱,一共 ...

  5. Codevs 1218 疫情控制 2012年NOIP全国联赛提高组

    1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...

  6. Codevs 3289 花匠 2013年NOIP全国联赛提高组

    3289 花匠 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 花匠栋栋种了一排花,每株花都 ...

  7. Codevs 1173 最优贸易 2009年NOIP全国联赛提高组

    1173 最优贸易 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description [问题描述] C 国有n ...

  8. Codevs 3731 寻找道路 2014年 NOIP全国联赛提高组

    3731 寻找道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找 ...

  9. Codevs 1138 聪明的质监员 2011年NOIP全国联赛提高组

    1138 聪明的质监员 2011年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 小 T 是一名质量监督员, ...

  10. Codevs 1217 借教室 2012年NOIP全国联赛提高组

    1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在大学期间,经常需要租借教 ...

随机推荐

  1. Windows平台调试器原理与编写02.一般断点与反汇编引擎

    https://www.bpsend.net/thread-256-1-2.html 一般断点(软件断点) 断点的尊严 断的下来 走的过去 下次还来 所有合格的断点都应该满足这3个要求 OD下断点实际 ...

  2. java客户端发送socket消息到指定服务并接收响应

    做个笔记 /** * 发送socket到指定服务 * 接收有6位报文头长度的响应,支持读取分包 * * @param host IP * @param port 端口 * @param msg 消息内 ...

  3. flutter3-winseek客户端AI实例|Flutter3.32+DeepSeek流式ai对话模板Exe

    原创首发flutter3+deepseek+window_manager客户端Ai流式打字Flutter-WinSeek. flutter3-winseek-chat:基于flutter3.32+da ...

  4. 详细剖析|袋鼠云数栈前端框架Antd 3.x 升级 4.x 的踩坑之路

    袋鼠云数栈从2016年发布第⼀个版本开始,就始终坚持着以技术为核⼼.安全为底线.提效为⽬标.中台为战略的思想,坚定不移地⾛国产化信创路线,不断推进产品功能迭代.技术创新.服务细化和性能升级. 在数栈过 ...

  5. Unity Shader入门精要个人学习笔记

    Unity Shader入门精要 渲染流水线 数学基础 1.点和矢量 类型 定义 表达 含义 性质 点(point) 点 (point) 是n 维空间(游戏中主要使用二维和三维空间)中的一个位置,它没 ...

  6. Selenium框架

    Selenium框架 Selenium是一个自动化测试工具,用于模拟用户在Web应用程序上的操作.它提供了多种编程语言的接口,如Python.Java等,使测试人员能够编写自动化测试脚本.Seleni ...

  7. HyperWorks分析模型的建立与边界条件施加

    在HyperWorks完成了基本的网格剖分后,还需要赋予模型各类与求解相关的信息,方能最终生成可以递交求解器计算的输入文件.分析模型的建立与载荷及边界条件的创建包括以下内容: -定义待输出的目标求解器 ...

  8. Web前端入门第 71 问:JavaScript DOM 节点操作(增删改)常用方法

    有一个深有体会的事:发现现在很多前端同学,经常用 Vue 开发项目之后,在某些需求场景要操作 DOM 节点的时,就不知道咋办了~~ 以前接手过其他开发团队的项目,项目被漏洞扫描工具发现了异常,原因是用 ...

  9. 解决了AI聊天的10个痛点后,我又做了一个新功能:交叉分析表

    前言 不久前,我写了一篇长文,吐槽了当前 Web 和桌面端 AI 聊天工具的 10 个体验问题.从"找不到几周前绝妙点子"的全局检索缺失,到"置顶所有等于没置顶" ...

  10. 解决IDEA总是将lombok注解处理器设置为unknown-lombok.jar

    背景 新建了一个SpringBoot项目,在项目中使用了lombok的注解,编译报错无法运行. 问题 具体表现为编译报错,大概如下图: 其原因是IDEA将lombok的注解处理器设置为了lombok- ...