• 模拟费用流问题略解


    参考自

    1. [PA2013]Raper((checkmark))

    2. [NEERC2016]Mole Tunnels

    • 一度想假/dk/dk
    • 考虑这么一个简单的建图,树的边之前彼此连边,流量无穷,费用为(1),鼹鼠向(p_i)连边,树的点向(T)连边((c_i,0))
    • 考虑增量-最小费用流模型(如果硬要套理论,我们可以假装每只鼠连边的费用都是(-inf),不过模拟的时候没差)
    • 考虑模拟费用流,注意到树高只有(log),我们可以考虑暴力来跳父亲,然后用数据结构维护一下最短路
    • 于是我们仅需支持维护以下操作
    • 将某个点的(c_u - 1)
    • 维护子树中距离最近的(u),满足(c_u != 0)
    • 将某条链的权值取反,因为树高是(log)的,这个手动做就可以了
    • 比较难维护的是取反操作,我们可以打标记,然后每次用栈存从要查询的点到根的标记,依次传下来即可,复杂度是(O(n log n))的,不需要栈以外的任何数据结构

    3.「ICPC World Finals 2018」征服世界((checkmark))

    • 首先有一个非常优秀的性质
    • 任两对点匹配,交叉一定不优
    • 我们有一个比较显然的费用流模型,即树彼此连边,费用为边权,军队,士兵向对应位置连边,军队必选,我们考虑模拟这个费用流
    • 以下内容夹带一定个人理解
    • 模拟费用流,我们并不一定要把思路局限在费用流那套理论上,局限在找负圈,找源汇路径上,事实上,能用费用流表示就意味着有许多优良的性质,如凸性,也间接证明了一类反悔贪心的正确性
    • 事实上,如果把思路局限在费用流的算法上,有时反而不好利用题目的一些特殊性质
    • 我们考虑这么一个反悔贪心,注意到两个点匹配是(dis_a + dis_b - 2 * dis_{lca})
    • 我们不妨设初始时(f_u = dis_u),如果是军队还要额外加上(-inf),那么每次匹配完((u,v)),都令(f_u:=-f_v + 2 * dis_{lca_(u,v)}),用可并堆维护,意味着反悔掉.
    • 但是这样有一个问题,如果两个都反悔,这样赋值就错了,甚至很难维护,但是,注意到任两个点一经匹配,不可能两个点都反悔,否则会交叉一定不优.这也保证了时间复杂度
    • (S = sum_ix_i)
    • 所以时间复杂度是(O(Slog S))
    • 事实上,如果我们将若干个权值一样的批量考虑,可以做到(O(nlog n))
    • AC code

    4. NOI2017蔬菜

    5.一个经典问题

    • 给一个长为(n)的序列,有正有负,要求你选(k)段不交区间,使得权值和最大
    • (n,k leq 2e5)
    • 考虑费用流模型是显然的,我们对每个点(u)拆成入点和出点,分别向源汇点连费用为(-sum_{u-1})(sum_u),流量为1的边,每个点初始时向后连边
    • 考虑模拟(EK)算法,每次增广一条,那么便是支持区间取反,我们用线段树维护能到左|右边的最大值,源汇点距离最大值,该段是否全向左|向右等等,小心转移一下即可
    • 据说可以用(mikisum)做到(Q)次区间询问
  • 相关阅读:
    gitolite 丢失管理密钥/访问权限 解决办法
    4/20
    socket套接字模块
    网络编程part2
    网络编程part1
    异常处理
    类的属性查找
    多继承带来的菱形问题
    property装饰器
    类的继承派生
  • 原文地址:https://www.cnblogs.com/y-dove/p/14787963.html
Copyright © 2020-2023  润新知