P5521 [yLOI2019] 梅深不见冬 题解
Step1 脑补fusu的行走过程,建立模型:
记对于
我们希望建立从叶子节点向根递推的关系。由此,不妨先考虑简单一些的初始情况:
当节点为叶子节点时,
当节点的孩子全都是叶子节点时:
我们记
其中拜访节点的序列是任意的,我们可以自己决定。
Step2 确定正确序列服从的贪心关系
所有孩子节点具有的数值为
把上面那个玩意揪出来,我们希望最小化的是:
不妨先取例测试,这里我取的是:
调整这些数对的顺序,我们发现无论怎样调整,答案都是
严格意义上,这里取
注意到最优的序列之一为:
运气很好,介于此及
Step3 复杂度分析+优化
遍历一遍树的复杂度:
孩子节点排序的总复杂度:
足以通过本题。
Step4 Coding
以下是主要代码:
bool cmp(node2 x,node2 y){
return (x.d-x.w)>(y.d-y.w);
}
void dfs(int u){
int cnt2=0;
for(int j=head[u];j!=0;j=edge[j].nxt){
int v=edge[j].v;
dfs(v);
d[u]+=w[v];
}
d[u]+=w[u];
for(int j=head[u];j!=0;j=edge[j].nxt){
int v=edge[j].v;
c[cnt2].w=w[v];
c[cnt2].d=d[v];
cnt2++;
}
if(cnt2==0){
return;
}
sort(c,c+cnt2,cmp);
int sumw=0;
for(int i=0;i<cnt2;i++){
d[u]=max(d[u],sumw+c[i].d);
sumw+=c[i].w;
}
}