P12007 【MX-X10-T3】[LSOT-4] 全国联赛?题解
一. 题面:点这里
二. 思路:
首先有一个比较常用的 trick 就是对于任意一颗带权树,对于题目中所求的两点对之间的距离和有如下公式:
\]
这个公式应当是容易理解的,那么最后的贡献就可以这么算,但是现在有一个连边的问题。这和最优化问题有关,可以 dp 吗?好像不太现实,那我们考虑贪心。一步步来,首先你肯定会有一个疑问就是如果要连边,应当连到这个连通块的哪一个点呢。因为连通块本身的点对之间距离是确定的,考虑其他连通块连过来时造成的贡献,显然我们应当让这个连接点到这个连通块其他部分的距离和最小(很好证明)。关于距离和最小这个问题是经典的,可以其中一个解法是可以考虑换根dp 。解决这个问题之后,我们就要考虑我们分别连接哪些联通块是最优的呢。让我们回到算贡献的式子,那么我们应当是希望这个图是菊花图(假设我们把所有连通块内部的点缩成一个点之后),这样可以最小化每一个形如 \(x(n-x)\) 的乘积式。问题是菊花图的中心是什么呢。我们猜想是连通块大小最大的那一个,证明考虑反证法,假设调换最大块和某一块的值,一定不会使答案变小,手搓一个二次函数图像之后就会发现这个问题等价于证明:任意一个正整数 \(t\) 表示不是最大块的大小都有:
\]
那么这是显然成立的(请读者自行思考,这是简单的。)
所以最后只需要以最大块向外连边即可,至于连边的顺序,考虑将边权大的连向乘积贡献小的连通块即可。
三. 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] 全国联赛?题解的更多相关文章
- Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...
- 树网的核 2007年NOIP全国联赛提高组(floyed)
树网的核 2007年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description [问题描述]设 T= ...
- 观光公交 2011年NOIP全国联赛提高组(贪心,递推)
观光公交 2011年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 风景迷人的小城 Y 市 ...
- Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
1069 关押罪犯 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description S 城现有两座监狱,一共 ...
- Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
1218 疫情控制 2012年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description H 国有 n 个城市,这 ...
- Codevs 3289 花匠 2013年NOIP全国联赛提高组
3289 花匠 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 花匠栋栋种了一排花,每株花都 ...
- Codevs 1173 最优贸易 2009年NOIP全国联赛提高组
1173 最优贸易 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description [问题描述] C 国有n ...
- Codevs 3731 寻找道路 2014年 NOIP全国联赛提高组
3731 寻找道路 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在有向图G中,每条边的长度均为1,现给定起点和终点,请你在图中找 ...
- Codevs 1138 聪明的质监员 2011年NOIP全国联赛提高组
1138 聪明的质监员 2011年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 小 T 是一名质量监督员, ...
- Codevs 1217 借教室 2012年NOIP全国联赛提高组
1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在大学期间,经常需要租借教 ...
随机推荐
- Windows平台调试器原理与编写02.一般断点与反汇编引擎
https://www.bpsend.net/thread-256-1-2.html 一般断点(软件断点) 断点的尊严 断的下来 走的过去 下次还来 所有合格的断点都应该满足这3个要求 OD下断点实际 ...
- java客户端发送socket消息到指定服务并接收响应
做个笔记 /** * 发送socket到指定服务 * 接收有6位报文头长度的响应,支持读取分包 * * @param host IP * @param port 端口 * @param msg 消息内 ...
- flutter3-winseek客户端AI实例|Flutter3.32+DeepSeek流式ai对话模板Exe
原创首发flutter3+deepseek+window_manager客户端Ai流式打字Flutter-WinSeek. flutter3-winseek-chat:基于flutter3.32+da ...
- 详细剖析|袋鼠云数栈前端框架Antd 3.x 升级 4.x 的踩坑之路
袋鼠云数栈从2016年发布第⼀个版本开始,就始终坚持着以技术为核⼼.安全为底线.提效为⽬标.中台为战略的思想,坚定不移地⾛国产化信创路线,不断推进产品功能迭代.技术创新.服务细化和性能升级. 在数栈过 ...
- Unity Shader入门精要个人学习笔记
Unity Shader入门精要 渲染流水线 数学基础 1.点和矢量 类型 定义 表达 含义 性质 点(point) 点 (point) 是n 维空间(游戏中主要使用二维和三维空间)中的一个位置,它没 ...
- Selenium框架
Selenium框架 Selenium是一个自动化测试工具,用于模拟用户在Web应用程序上的操作.它提供了多种编程语言的接口,如Python.Java等,使测试人员能够编写自动化测试脚本.Seleni ...
- HyperWorks分析模型的建立与边界条件施加
在HyperWorks完成了基本的网格剖分后,还需要赋予模型各类与求解相关的信息,方能最终生成可以递交求解器计算的输入文件.分析模型的建立与载荷及边界条件的创建包括以下内容: -定义待输出的目标求解器 ...
- Web前端入门第 71 问:JavaScript DOM 节点操作(增删改)常用方法
有一个深有体会的事:发现现在很多前端同学,经常用 Vue 开发项目之后,在某些需求场景要操作 DOM 节点的时,就不知道咋办了~~ 以前接手过其他开发团队的项目,项目被漏洞扫描工具发现了异常,原因是用 ...
- 解决了AI聊天的10个痛点后,我又做了一个新功能:交叉分析表
前言 不久前,我写了一篇长文,吐槽了当前 Web 和桌面端 AI 聊天工具的 10 个体验问题.从"找不到几周前绝妙点子"的全局检索缺失,到"置顶所有等于没置顶" ...
- 解决IDEA总是将lombok注解处理器设置为unknown-lombok.jar
背景 新建了一个SpringBoot项目,在项目中使用了lombok的注解,编译报错无法运行. 问题 具体表现为编译报错,大概如下图: 其原因是IDEA将lombok的注解处理器设置为了lombok- ...