题目大意

给出一个二叉树,每个点有点权 d i d_i di​,按顺序切断它的 n − 1 n−1 n−1条边,代价是边所连的两个点的权值和,且断边之后两点会交换权值,你的目的是最小化权值和。
n ≤ 5 e 3 n\le5e3 n≤5e3

solution

实乃毒瘤 d p dp dp
很容易想到树形 d p dp dp,但是发现很难设置状态,题目中有一个重要条件,该树是棵二叉树,不妨先观察不同情况的不同短边顺序的点的移动情况

不难发现无论是什么情况,当且仅当一个点经过父边从子树外进来到位置 v v v,一个点 u u u经过父边从子树内出去,且它们的 l c a lca lca为 r r r,即当前讨论的点
所以可以设出状态 f u , v , r = l c a ( u , v ) f_{u,v},r=lca(u,v) fu,v​,r=lca(u,v)表示 r r r子树内和 r r r到父亲的边被断, u u u点被移出去,一个点被移到 v v v的最小代价,由于还不知道移进来的是哪个点,所以这个最小代价并不算移进来的点的代价,移进来的点将会在之后的转移中被确定并且代价会被计算

设儿子个数为 d e g r deg_r degr​,深度为 d e p u dep_u depu​,儿子为 l s u , r s u ls_u,rs_u lsu​,rsu​

d e g r = 0 deg_r=0 degr​=0

显然只有 f r , r = d r f_{r,r}=d_r fr,r​=dr​

d e g r = 1 deg_r=1 degr​=1

观察前面的图不难发现要么 u = r u=r u=r,要么 v = r v=r v=r

u = r u=r u=r时

f u , v = min ⁡ { f i , v + d u } , l c a ( i , v ) = l s u f_{u,v}=\min\{f_{i,v}+d_u\},lca(i,v)=ls_u fu,v​=min{fi,v​+du​},lca(i,v)=lsu​

v = r v=r v=r时

f u , v = min ⁡ { f u , j + d u + d r ( d e p j − d e p r ) } , l c a ( u , j ) = l s u f_{u,v}=\min\{f_{u,j}+d_u+d_r(dep_j-dep_r)\},lca(u,j)=ls_u fu,v​=min{fu,j​+du​+dr​(depj​−depr​)},lca(u,j)=lsu​

d e g r = 2 deg_r=2 degr​=2

u = r u=r u=r时

f u , v = min ⁡ { f i , j + f k , v + d r + d k ( d e p j − d e p r ) } , l c a ( i , j ) = l s u , l c a ( k , v ) = r s u f_{u,v}=\min\{f_{i,j}+f_{k,v}+d_r+d_k(dep_j-dep_r)\},lca(i,j)=ls_u,lca(k,v)=rs_u fu,v​=min{fi,j​+fk,v​+dr​+dk​(depj​−depr​)},lca(i,j)=lsu​,lca(k,v)=rsu​
f u , v = min ⁡ { f i , j + f k , v + d r + d k ( d e p j − d e p r ) } , l c a ( i , j ) = r s u , l c a ( k , v ) = l s u f_{u,v}=\min\{f_{i,j}+f_{k,v}+d_r+d_k(dep_j-dep_r)\},lca(i,j)=rs_u,lca(k,v)=ls_u fu,v​=min{fi,j​+fk,v​+dr​+dk​(depj​−depr​)},lca(i,j)=rsu​,lca(k,v)=lsu​
直接这样转移时 O ( n 4 ) O(n^4) O(n4),的,但是观察发现可以分别枚举 i , j i,j i,j、 j , k j,k j,k、 k , v k,v k,v,时间复杂度是 O ( n 2 ) O(n^2) O(n2)的

v = r v=r v=r时

同理

u ≠ r , v ≠ r u\not = r,v\not =r u​=r,v​=r时

同理

r = 1 r=1 r=1时就不做了,直接分析 d e g 1 deg_1 deg1​的情况来统计答案
所以总时间复杂度就是 O ( n 2 ) O(n^2) O(n2)的
代码实现比较复杂,枚举 l c a ( u , v ) = r lca(u,v)=r lca(u,v)=r的点对 ( u , v ) (u,v) (u,v)时可以合理的利用 d e f i n e define define来优化代码长度

code

#include<cstdio>
#include<algorithm>
#include<vector>
#define ll long long
#define fori(u) for(int _i=dfn[u],i=u;_i<=dfn[u]+siz[u]-1;_i++,i=id[_i])
#define forj(u) for(int _j=dfn[u],j=u;_j<=dfn[u]+siz[u]-1;_j++,j=id[_j])
#define fork(u) for(int _k=dfn[u],k=u;_k<=dfn[u]+siz[u]-1;_k++,k=id[_k])
#define forh(u) for(int _h=dfn[u],h=u;_h<=dfn[u]+siz[u]-1;_h++,h=id[_h])
#define forlca(u,expr) fori(son[0][u]) forj(son[1][u]) expr fori(son[1][u]) forj(son[0][u]) expr i=u;forj(u) expr j=u;fori(u) expr;
using namespace std;
void read(int &res)
{res=0;char ch=getchar();while(ch<'0'||ch>'9') ch=getchar();while('0'<=ch&&ch<='9') res=(res<<1)+(res<<3)+(ch^48),ch=getchar();
}
void read(ll &res)
{res=0;char ch=getchar();while(ch<'0'||ch>'9') ch=getchar();while('0'<=ch&&ch<='9') res=(res<<1)+(res<<3)+(ch^48),ch=getchar();
}
const int N=5e3+10;
const ll inf=1e17;
int n,fa[N+10],son[2][N+10],deg[N+10],dfn[N+10],id[N+10],siz[N+10],dep[N+10];ll d[N+10],f[N+10][N+10],g1[N+10],g2[N+10];
void dfs(int u)
{dfn[u]=++dfn[0],id[dfn[0]]=u,siz[u]=1,dep[u]=dep[fa[u]]+1;if(son[0][u]) dfs(son[0][u]),deg[u]++,siz[u]+=siz[son[0][u]];if(son[1][u]) dfs(son[1][u]),deg[u]++,siz[u]+=siz[son[1][u]];
}
int main()
{freopen("mis.in","r",stdin);freopen("mis.out","w",stdout);read(n);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f[i][j]=inf;for(int i=1;i<=n;i++) read(d[i]);for(int i=2;i<=n;i++){read(fa[i]);if(son[0][fa[i]]) son[1][fa[i]]=i;else son[0][fa[i]]=i;}dfs(1);for(int r=n,i,j;r>=2;r--){if(deg[r]==0) f[r][r]=d[r];if(deg[r]==1){int u=son[0][r];forlca(u,f[r][j]=min(f[r][j],f[i][j]+d[r]););forlca(u,f[i][r]=min(f[i][r],f[i][j]+d[i]+d[r]*(dep[j]-dep[r]));); }if(deg[r]==2){for(int t=0,v0,v1;t<=1;t++){v0=son[t][r],v1=son[t^1][r];fori(r) g1[i]=g2[i]=inf;forlca(v0,g1[j]=min(g1[j],f[i][j]););forj(v0) fork(v1) g2[k]=min(g2[k],g1[j]+d[k]*(dep[j]-dep[r]));forlca(v1,f[r][j]=min(f[r][j],f[i][j]+g2[i]+d[r]););}for(int t=0,v0,v1;t<=1;t++){v0=son[t][r],v1=son[t^1][r];fori(r) g1[i]=g2[i]=inf;forlca(v0,g1[i]=min(g1[i],f[i][j]+d[r]*(dep[j]-dep[r])););fori(v0) forh(v1) g2[h]=min(g2[h],g1[i]+d[i]*(dep[h]-dep[r]));forlca(v1,f[i][r]=min(f[i][r],f[i][j]+g2[j]+d[i]););}for(int t=0,v0,v1;t<=1;t++){v0=son[t][r],v1=son[t^1][r];fori(r) g1[i]=g2[i]=inf;forlca(v0,g1[j]=min(g1[j],f[i][j]););forlca(v1,g2[i]=min(g2[i],f[i][j]+d[r]*(dep[j]-dep[r])););fork(v1) forj(v0) f[k][j]=min(f[k][j],g2[k]+g1[j]+d[k]);}}}int i,j;ll ans=inf;if(deg[1]==1){forlca(son[0][1],ans=min(ans,f[i][j]+d[1]*(dep[j]-dep[1])););}if(deg[1]==2){for(int t=0,v0,v1;t<=1;t++){v0=son[t][1],v1=son[t^1][1];fori(1) g1[i]=g2[i]=inf;forlca(v0,g1[j]=min(g1[j],f[i][j]););forlca(v1,g2[i]=min(g2[i],f[i][j]+d[1]*(dep[j]-dep[1])););forj(v0) fork(v1) ans=min(ans,g1[j]+g2[k]+d[k]*(dep[j]-dep[1]));}}printf("%lld",ans);return 0;
}

P8294 [省选联考 2022] 最大权独立集问题相关推荐

  1. 大连大学两日游———2021省选联考游记

    大连大学两日游---2021省选联考游记 今年高一,今年省选就是去积累大赛经验的,为明年的主场做准备.考前参加过几次学校组织的模拟赛(死难死难 ),都得了不点分,所以本来就没多大目标,不爆零就行,但是 ...

  2. P7516-[省选联考2021A/B卷]图函数【bfs】

    正题 题目链接:https://www.luogu.com.cn/problem/P7516 题目大意 懒了,直接抄题意了 对于一张 nnn 个点 mmm 条边的有向图 GGG(顶点从 1∼n1 \s ...

  3. 【学习笔记】[省选联考 2023] 填数游戏

    我不好说,因为考场上我想成二分图然后就gg了 这题不难,真的不难. ∣ T i ∣ ≤ 2 |T_i|\le 2 ∣Ti​∣≤2这个性质一看就非常亲切啊,可以看成一条 a i a_i ai​到 b i ...

  4. [省选联考 2020 A/B 卷] 信号传递(状压dp + 卡空间)

    problem luogu-P6622 一条道路上从左至右排列着 mmm 个信号站,初始时从左至右依次编号为 1,2,-,m1,2,\dots,m1,2,-,m,相邻信号站之间相隔 111 单位长度. ...

  5. [省选联考 2020 A/B 卷] 冰火战士(树状数组上二分)

    文章目录 problem solution(10pts) code(10pts) solution(30pts) code(30pts) solution(60pts) code(60pts) sol ...

  6. P6620 [省选联考 2020 A 卷] 组合数问题(斯特林数、下降幂)

    解析 给出 n,x,pn,x,pn,x,p 和一个 mmm 次的多项式 f(k)f(k)f(k),求解: ∑k=0nf(k)xk(nk)modp\sum_{k=0}^nf(k)x^k\binom n ...

  7. P7516 [省选联考 2021 A/B 卷] 图函数

    解析 纯纯的人类智慧题. 关键性质:vvv 可以在计算 f(u,G)f(u,G)f(u,G) 时产生贡献,当且仅当 GGG 中 u,vu,vu,v 之间可以通过 [v,n][v,n][v,n] 的点互 ...

  8. P7520-[省选联考 2021 A 卷]支配

    正题 题目链接:https://www.luogu.com.cn/problem/P7520 题目大意 给出nnn个点mmm条边的一张有向图,一号点为起始点,qqq次独立的询问加入一条边后有多少个点的 ...

  9. P7519-[省选联考 2021 A/B 卷]滚榜【状压dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P7519 题目大意 nnn个队伍,队伍之间按照得分从小到大排名,得分相同的按照编号从小到大排.开始时每个队伍有个初始 ...

最新文章

  1. 百度飞桨全新升级:重磅推出PaddleHelix平台、开源框架V2.0RC,硬件生态路线图全公开...
  2. ITK:两条曲线上所有点之间的平均距离
  3. tdms打开闪退问题
  4. java基础应用_Java基础(应用篇)
  5. matlab freqs函数用法,Matlab freqs 函数
  6. vb与数据库(二)之迟到的学生信息管理系统总结
  7. 向前、向后、横着走,双足机器人Cassie,靠深度强化学习学会了走路丨论文
  8. win10风格美化以及新建系统后优化
  9. 论如何用cmd命令做出数字雨特效
  10. 一款好用、易扩展的文件解析引擎,是怎么演变而来的
  11. 【物理学】扫描隧道显微镜(Scanning Tunneling Microscope)
  12. quick Cocos2dx lua 接anysdk
  13. 读书札记:音律的基本类型
  14. python实现 Python蟒蛇绘制(嵩天老师 )
  15. ESXi 社区版网卡驱动
  16. 软件测试慕课版学习总结—第二章
  17. linux下u盘怎么找,redhat怎么找到u盘呢 ?
  18. 基于java的高校实验室排课系统
  19. python中seed的相关代码
  20. 微软亚研副院长周明离职,将出任创新工场AI工程院首席科学家

热门文章

  1. php实现新闻浏览量,thinkphp实现统计页面浏览量
  2. Threejs使用白底贴图时,显示出来的图片为灰底
  3. 爬取某公司特定年份年报+年报表格信息提取
  4. Python实现小病毒
  5. 火车头采集:高效数据采集工具的介绍
  6. 民营物流公司迫切需要政策支持
  7. java生成pem格式公钥_如何以.pem格式保存证书中的公钥
  8. 资深建模师给小白的建议,如何正确认识这个行业
  9. JMeter之Websocket测试
  10. 【一天时间|JavaScript进阶】函数式编程高阶函数的应用