[COCI2020-2021#2] Sjekira 题解
题目大意:把一棵树完全分解,每次分解一条边的代价是这条边连接的两个连通块的最大点权之和,求最小代价。
逆序模拟,既然题目要求将树完全分解,那我们就每次逆序连接当前权值最小的两个点,也就是贪心的思路。
尝试将贪心的值写成一个表达式:
\[\sum_{i=1}^n a_i+\sum_{(u,v)\in E} \max(a_u,a_v)-\max(a_i)
\]
考虑转化为合并节点,设第一次合并的时候代价为 \(a_i\),那如果 \(a_i>a_j\) 就要再操作一次 \(a_i\),所以边加的就是两个端点的最大值(作为新的连通块的最大代价的点对答案产生贡献,但是发现多一项,减一个 \(\max(a_i)\) 即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a,s,d[100005],f;
ll ans,sum=-99999;
int main(){
scanf("%lld",&a);
for(int i=1;i<=a;i++){
scanf("%lld",&d[i]);
ans+=d[i];
sum=max(sum,d[i]);
}
for(int i=1;i<a;i++){
scanf("%lld%lld",&s,&f);
ans+=max(d[s],d[f]);
}
printf("%lld",ans-sum);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通