zoukankan      html  css  js  c++  java
  • [NOIP2012]疫情控制

    你为什么要读这篇文章(本文涉及的内容):本题(包括增强版)的算法的详细描述与贪心的正确性证明。

    解答

    2020-03-12 edit:

    偶然翻到这篇博文,感觉自己写的题解是真的太毒瘤了……连我自己都看不懂自己写了啥。

    做了一点修改与补充,enjoy!

    二分答案+贪心。

    约定

    下文中,我们:

    • (d(u,v))表示在树上(u)(v)两点之间的距离,
    • (tree(u))表示(u)的子树内的所有节点的集合,
    • (son(u))表示(u)的所有儿子节点的集合,
    • (leaf(u)subseteq tree(u))表示(tree(u))中的所有叶子节点。

    初步

    考虑(leaf(u))被控制的充分必要条件:

    • 存在军队(x)(u)的祖先,或
    • 对于每一个(vin son(u))(leaf(v))都已经被控制。

    为了简化问题,我们先考虑在二分到(mid)时,哪些军队的位置是固定的。

    显然,对于那些“不能到达根节点”,即(d(x,1)>mid)的军队(x),尽量向上移动是最优的。

    那么,可以用倍增(O(log n))时间内处理出这些军队的最终位置,可以通过 DFS 求出根的哪些儿子的子树(的叶节点)没有被(完全)控制,设其集合为(S_1subseteq son(1))。(显然,其他节点都部署在根的儿子上)

    贪心

    之后,就是考虑能够到达根(1)的节点如何部署的问题了。由于离根越远的儿子越难满足,根据贪心的原则,优先考虑离根最的儿子(u)

    1. 如果(u)的子树内有可以到达(u)的军队,取距根最的(可部署的)(x)部署。
    2. 否则(或者该子树内所有军队均已被部署),取到(1)的军队(x)部署。

    一个实现上的优化:若(u)的子树内可以到达(u)且离(u)最远的军队已经被部署,则(u)的子树内已经没有未被部署的军队(因为总是由近到远选择军队部署),直接转到2即可。

    正确性

    若某个可行解里(x)部署到了(vin S_1,v e u)上(或者没有部署,此时正确性是显然的),考虑该解中,部署在(u)的军队(x'),则其可以与(x)交换部署的位置。我们来证明这一点。

    有假设,显然有(d(x',u)le mid,d(x,v)le mid)。此外,(x)一定可以部署到(u)上,有(d(x,u)le mid)

    故我们只需要说明(x')可以部署在(v)上,即(d(x',v)le mid)即可。我们来分情况说明这一点:

    以下的证明为了不把行内公式写得太长,跳过了一些步骤。

    具体证明最多只需用到(d(x,y)le d(x,z)+d(z,w)),就作为留给读者的练习了~

    1. (x)(u)子树内:此时(d(x,v)=d(x,u)+d(u,v))
      1. (x')(u)子树内:
        • 此时(d(x',v)=d(x',u)+d(u,v))
        • 则由(x)的距离(1)的最远性,有(d(x',v)le d(x,v)le mid)
        • (x')能部署在(v)上。
      2. 否则,(x')不在(u)子树内:
        • 则由(u)距离(1)的最远性,有(d(u,1)ge d(v,1))
        • 可得到(d(x',v)le d(x',u)le mid)
        • (x')能部署在(v)上。
    2. (x)不是(u)子树内的节点:显然此时(x')不可能在(u)子树内。
      • 则由1.2的证明方法,可得(d(x',v)le d(x',u)le mid)

    那么(基本上只需要按照上面的描述)直接写就可以了。(注意细节……这题毕竟是个紫题……)

    LOJ上的加强版

    加强版的数据要求算法复杂度只能一个(log),怎么办?

    显然,二分答案这一步是没办法去掉的……只能尝试把判断可行性优化到(O(n))

    注意到在(mid)时间内处理出(不)可以到(1)的军队是简单的:预先处理出所有(d(x,1))并排序,则答案为一个它的一个前缀。

    考虑不倍增怎么求(1)的“哪些(uin son(v))的子树被控制”。换句话说,对于一个节点(uin son(1)),我们需要知道:

    1. 它的(所有)子树是否全部被(完全)控制。
    2. 有没有一个军队可以到(u)(的祖先),即是否存在(x)满足(d(x,1)>mid,d(x,u)le mid)

    标记那些(d(x,1)>mid)的军队(x)(在树上的位置),在 DFS 到(u)时显然可以所有(vin son(u))的子树是否被控制,以及节点(u)距离最近的(xin tree(u))的距离,判断是否有(d(x,u)le mid)即可。

    LOJ最短代码 (写文章时)

  • 相关阅读:
    Mysql-学习笔记(==》事件 十二)
    Mysql-学习笔记(==》触发器 十一)
    Mysql-学习笔记(==》函数的建立与使用 十)
    Mysql-学习笔记(==》存储过程 九)
    Mysql-学习笔记(==》常用函数 八)
    Mysql-学习笔记(==》增删主键建立索引 七)
    Mysql-学习笔记(==》约束 六)
    Mysql-学习笔记(==》集合函数与分组四)
    Mysql-学习笔记(==》连接查询_高级查询五)
    Unity3D优化技巧系列七
  • 原文地址:https://www.cnblogs.com/topsecret/p/11798426.html
Copyright © 2011-2022 走看看