2020 CCPC-Wannafly Winter Camp Day3 G-火山哥周游世界
令len[x]表示特殊点(即要去的地方)到u的距离。 那么从u出发 走完所有特殊点所需要的代价是 2 [sigma(len[x])]-max(len[x]) 令dp[u]表示从小到上,特殊点到u的距离和。我们如果从1出发,sigma(len[x])就可以通过一次dfs求得。我们令sum表示距离和。 当1的子节点为根节点的时候,假设为u。当u的子树有特殊点,sum-=2 wi。当u除了子树外,还有特殊点,sum+=2*wi。 接着我们计算max(len[x])。这个就是树上任意一点,其他点到这个点的最长距离。我们利用记录最大值和次大值dp来解决这个问题。 令maxx[u]表示u的子树中,到u的最长距离。maxx2[u]表示次长距离。令nxt[u]表示u的最长距离链上,u的直接子节点。 同样,因为特殊点可能在u的子树之外,所以令famax[u]表示,u向上走的最大距离。 对于u的任意一个子节点v,我们可以得到一个dp表达式: if(v==nxt[u])famax[v]=max(famax[u]+wi,maxx2[u]+wi) else famax[v]=max(famax[u]+wi,maxx[u]+wi)。 故我们求得 1为根节点后,max和sigma值可以根据1节点的答案dp出来。 #include<iostream> #include<cstring> #include