• Codeforces 468D Tree


    题目

    给出一棵带边权的树,求一个排列(p),使得(sum_{i=1}^{n}{dis(i, p_i)})的值最大,其中(dis(v, u))表示(v)(u)的距离。

    算法

    这题的思路非常巧妙,又是和重心有关的题目!记得ydc的大树这题的ydc的做法有异曲同工之妙。

    首先我们列答案的计算公式:$$sum_{i=1}^{n}{dep_i+dep_{p_i}-dep_{lca(i,p_i)}}$$
    其中(dep(i))(i)到根的距离,(lca(v,u))就不用说了吧。
    上面的式子等价于$$2 sum_{i=1}{n}{p_i}-sum_{i=1}{n}{dep_{lca(i,p_i)}}$$
    我们就要使(sum_{i=1}^{n}{dep_{lca(i,p_i)}})最小化。

    找到树的重心(root),并使它 变为根,显然我们有一种方法,使得(lca(i,p_i))都是(root),所以答案就是(2 sum_{i=1}^{n}{p_i})

    难点在求字典序最小的排列(p)

    我们可以按(1)(n)的顺序依次确定(p_i),根据贪心,我们每次必然选标号最小的点(j)。而且这个点要满足:

    • (lca(i,j)=root),我们可以把(root)去掉,那么一棵树就裂成了若干“小树”,那么就是要满足(i)(j)不在同一个小树。
    • 仅仅满足上面的条件是不够的,因为有可能出现(i)(j)只能在同一个小树的情况,所以我们要稍加限制:如果某个小树里出现了标号大于i的结点数量+还没有被选的结点数量=(n-i),那么,(i)(j)之一 一定要在这个小树里。

    我的代码

  • 相关阅读:
    centos8.0 安装 jenkins
    No match for argument: mysql-community-server Error: Unable to find a match: mysql-community-server
    Navicat 远程连接 centos8.0
    centos8.0 安装 mysql
    -bash: java-version: command not found
    centos8.0 安装 JDK1.8
    [Err] 1062
    android之Fragment基础详解(一)
    Android之RecyclerView(一)
    Android之ProgressBar
  • 原文地址:https://www.cnblogs.com/wangck/p/4372793.html
Copyright © 2020-2023  润新知