当前位置: 首页 > news >正文

最后防线 解题报告

简要题意

给定一棵 \(n\) 个节点的有根树,每个点有点权 \(a\)。求出一个访问顺序,使得所有点都在其祖先之后被访问,设第 \(i\) 个节点是第 \(p_i\) 个被访问到的,最小化 \(\sum \limits_{1\ le i \le n}p_ia_i\)

数据范围:\(n \le 2\times 10^4\)

分析

首先考虑没有访问顺序限制怎么做。那么就贪心地先访问点权最大的点即可。

那么加入访问顺序呢?我们考虑当前权值最大的点,那么我们一定要尽可能优先访问它,但是它再先也不能超过它父亲。总之就是这个点一定在它父亲下一个被访问,那么我们就可以考虑合并这两个点,然后就变成子问题。

那么我们考虑合并要合并什么:权值和个数。

那么怎么确定谁先谁后呢?考虑相邻两个点交换后对总代价的影响,这是 naive 的。

最后用一个支持删除、插入、访问最小元素的数据结构维护即可。

代码

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define Inf (1ll<<60)
#define For(i,s,t) for(int i=s;i<=t;++i)
#define Down(i,s,t) for(int i=s;i>=t;--i)
#define ls (i<<1)
#define rs (i<<1|1)
#define bmod(x) ((x)>=p?(x)-p:(x))
#define lowbit(x) ((x)&(-(x)))
#define End {printf("NO\n");exit(0);}
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
inline void ckmx(int &x,int y){x=(x>y)?x:y;}
inline void ckmn(int &x,int y){x=(x<y)?x:y;}
inline void ckmx(ll &x,ll y){x=(x>y)?x:y;}
inline void ckmn(ll &x,ll y){x=(x<y)?x:y;}
inline int min(int x,int y){return x<y?x:y;}
inline int max(int x,int y){return x>y?x:y;}
inline ll min(ll x,ll y){return x<y?x:y;}
inline ll max(ll x,ll y){return x>y?x:y;}
char buf[1<<20],*p1,*p2;
#define gc() (p1 == p2 ? (p2 = buf + fread(p1 = buf, 1, 1 << 20, stdin), p1 == p2 ? EOF : *p1++) : *p1++)
#define read() ({\int x = 0, f = 1;\char c = gc();\while(c < '0' || c > '9') f = (c == '-') ? -1 : 1, c = gc();\while(c >= '0' && c <= '9') x = x * 10 + (c & 15), c = gc();\f * x;\
})
void write(int x){if(x>=10) write(x/10);putchar(x%10+'0');
}
const int N=2e5+100;
int n,rt,fa[N],nxt[N],f[N],a[N],tot;
int find(int x){return f[x]=(f[x]==x ? x : find(f[x]));}
ll ans;
bool vis[N];
struct Node{int u,ed;ll f,t;bool operator <(const Node x) const{return f*x.t>x.f*t || (f*x.t==t*x.f && u<x.u);}bool operator >(const Node x) const{return f*x.t<x.f*t || (f*x.t==t*x.f && u>x.u);}
}b[N];
set<Node> s;
int main()
{
#if !ONLINE_JUDGEfreopen("line.in","r",stdin);freopen("line.out","w",stdout);
#endif n=read(),rt=read();For(i,1,n) a[i]=read(),f[i]=i;int x,y;For(i,2,n) x=read(),y=read(),fa[y]=x;For(i,1,n) s.insert(b[i]=Node{i,i,a[i],1});vis[0]=true;while(!s.empty()){Node tp=*s.begin();s.erase(tp);int u=tp.u,p=find(fa[u]);if(vis[fa[u]]){ans+=(tot+1)*b[u].f;tot+=b[u].t;while(u) vis[u]=true,u=nxt[u];continue;}s.erase(b[p]);ans+=b[u].f*b[p].t;b[p].f+=b[u].f;b[p].t+=b[u].t;nxt[b[p].ed]=u;f[u]=b[p].u;b[p].ed=b[u].ed;s.insert(b[p]);}printf("%lld",ans);return 0;
}
http://www.rkmt.cn/news/22370.html

相关文章:

  • AI时代我们需要更多开发者:Shalini Kurapati的技术洞察
  • 从此,不再开口就紧张
  • 基于Qt实现百度地图路径规划功能
  • 基于C#的湿度上位机实现方案
  • C盘满了怎么清理?10种安全释放Win10/Win11空间的方法(详细图文版)
  • 2025 护眼灯生产厂家最新推荐榜:精选资深与新锐品牌,深度解析生产实力与市场口碑
  • 【IEEE出版|快至3-4个月EI检索】第五届电力系统与能源互联网国际学术会议(PoSEI 2025)
  • 复盘:如何用Coze+Kimi,搭建一个能自动分析财报的“金融助理”?
  • 详细介绍:【算法竞赛学习笔记】基础算法篇:递归再探
  • 折腾笔记:免费用上 Claude Code 的两个方案
  • 2025 年最新金蝶云服务商代理机构权威推荐排行榜:聚焦铂金伙伴技术实力与万级客户口碑,上海金蝶云最新推荐优质公司
  • 可视化图解算法64:哈希表基础
  • SqlServer Arithmetic overflow error converting expression to data type int
  • 医疗公有云市场第一!
  • 2025手持光谱仪/光谱分析仪/便携式光谱仪、矿石/元素分析仪、合金/金属/不锈钢/铝合金、贵金属、三元催化、赛普斯、IF光谱仪推荐榜
  • 在 Android 11 上构建 WiFi 热点并发协助(同时开启 STA + AP 模式)
  • 25 LCA模拟赛3T1 ROI 2012马赛克 题解
  • uni-app x开发商城系统,Swiper 轮播图
  • 昂瑞微OM6651A:国产车规级蓝牙芯片的破局者
  • 打破应用跳转流失困局,提升推广链接转化率
  • 检查cpu是否支撑minio方法
  • Codeforces Round 1058 (Div. 2) A~E
  • 2025 年生料带厂家最新推荐排行榜:解析优质品牌优势,涵盖新型、彩色、液态等多类型生料带厂家企业推荐
  • openresty开发lua-resty-openssl之对称加密解密 - liuxm
  • 腾讯云 OpenCloudOS 8 docker安装
  • 哈希乱搞:CF1418G Three Occurrences
  • 悲伤 自卑 乖戾 独自哭泣 陪伴空虚 kill my memory 让我将痛苦全忘记
  • 工程师的 “指尖实验室”!正点原子 LT1 电桥镊子深度测评:同价位竞品谁能打?
  • 破解跨域监控难题:国标GB28181算法算力平台EasyGBS视频调阅技术在跨域安防监控中的核心应用
  • 2025 年电缆桥架源头厂家最新推荐排行榜:聚焦优质供应商核心竞争力,助力工程采购精准选型