zoukankan      html  css  js  c++  java
  • 【学习笔记】集训队论文阅读

    集训队论文阅读笔记-姜志豪-网络流的一些建模方法

    最大流建模

    Luogu-P4311 士兵占领

    写一下自己的办法。

    考虑一个类似的问题”一行最多 (l_i) 个士兵,一列最多 (c_i) 个士兵,求最多放多少个士兵“。这个问题可以通过一行一个点,一列一个点,如果位置 (a_{i,j}) 可以放人,就将 (i) 行与 (j) 列之间连边。

    那么如何解决原问题?考虑原问题等价于每个位置上已经有 (x) 个兵,现在要去掉一些兵,但剩下的每行每列的总兵数有下线,求最后剩下的兵数最小多少个。所以限制等价于去掉的兵的数量有上限,就可以用上面说的问题求解了。

    Dining

    其实这题可以推广的。

    如果推广成 1 只奶牛对应 3 个方面的东西,我不会做。

    但是如果推广成两种奶牛,第一种奶牛需要A和B两种方面的东西,第二种奶牛需要B和C两种方面的东西,两只奶牛可以呆在一块当且仅当:这两只奶牛属于不同种,并且喜好的 B 东西一样。求最多多少对奶牛呆在一块并且三种东西都能满足他们的需求。

    做法:可以考虑如下建图:东西 -> 奶牛 -> 东西 -> 奶牛 -> 东西(与奶牛相邻的是他喜欢的东西)。

    Collector’s Problem

    Friend 可以做的只是将 Bob 已有的卡片换成别的卡片。

    考虑如下建图:

    • 每个卡片、人都有一个节点
    • 如果 Friend 没有卡片 a ,那么卡片 a 向 Friend 连一条边。表示别人可以给 Friend 卡片 a 。
    • 如果 Friend 有至少两张卡片 a ,那么 Friend 向卡片 a 连边。表示 Friend 可以给别人卡片 a 。
    • 起点向所有 Bob 有的卡片连一条容量为 Bob 这张卡片的数量。
    • 每张卡片向终点连一条容量为 1 的边。

    最大流即为答案。

    最小割建模

    用容量为正无穷的边表示冲突

    【NOI 2006】 最大获利

    这题很有迷惑性。这里一个用户依赖两个站点,所以很容易就想用一条边表示用户。然而这样并不能走通。

    就当成一个用户依赖两个站点就好了。答案就是 利润之和 (-) 得不到的利润 (-) 成本。也就是得不到的利润 (+) 成本最小即可。

    这样考虑最小割建图:

    • 一个用户代表一个点
    • 一个站点代表一个点
    • 用户向两个依赖的点连边,边权为正无穷
    • 起点向用户连边,边权为用户付的钱
    • 站点向终点连边,边权为修建站点的代价

    那么一个路径,S->用户->站点->T 中 S->用户 与 站点->T 之中必然有一个要割掉。

    【Codechef Dec14】 Course Selection

    这就比较巧妙了。还是最小割建图。

    建图要分部建图。先建出满足某些条件的,再不断完善。

    将最大得分转化为最小扣分(也就是 (s_{i,j}) 表示 (100-x_{i,j}) ,让所有课程的 (s_{i,j}) 和最大)。考虑建出不满足先后顺序的图,再在这基础上改进。

    可以考虑这样:

    • ((i,j))((i+1,j)) 连边,其中 ((i,j)) 表示第 (i) 学期学习第 (j) 个科目。(s)((i,1)) 连边,边权为 (s_{i,j})
    • 割掉 (s_{i,j}) 表示选择了 (i) 这个学期上 (j) 这门课。

    那么如何满足先后顺序呢?

    可以考虑这样:

    • (a) 课程在 (b) 之前上,那么对于所有 ((i,a)) ,向 ((i+1,b)) 连边。
    • 对于存在 (a) 课程在 (b) 之前上,那么 (s)((i,b)) 连一条容量为 inf 的边。

    从两点关系的角度进行最小割建模

    happiness

    要点:

    • 这样的建图结构,如果 (x)(y) 最终不连通(也就选择是 (x) 保留 (a)(y) 保留 (d)),则需要割掉边 (e)

    这题好像和文理分科还不太一样。。

    考虑一个点代表一个人,如果保留和 (s) 的连边,就代表选择了文科,如果保留和 (t) 的连边,就代表选择了理科。

    考虑一对好朋友 (x)(y)

    如果 (x)(y) 都选了文科,那么需要增加喜悦值。也就相当于,选的科目不一样就减少喜悦值。

    所以考虑 (x)(y) 之间连接一条边,权值为选择不同科目减少的值。这样如果保留了 (x)(s) 的边,(y)(t) 的边,中间这条边就必须删掉。

    Google Code Jam 2008 Final E, The Year of Code Jam

    要点:

    • 黑白染色(只可意会不可言传)
    • 最小割连边不一定是有向的,仔细体会有向边的作用。

    这个题其实大部分和上一道题一样,区别在于如果相同则减收益,上一道题是如果不同则减收益。就是将上一道题反过来了。

    那么考虑黑白染色:

    • 黑色点:
      • (s) 相连打比赛
      • (t) 相连不打
    • 白色点:
      • (s) 相连不打比赛
      • (t) 相连打比赛

    照样一个点与相邻的点连边,表示额外损失。

    这样会发现,如果黑色点与 (s) 连边,他相邻的白色点与 (t) 连边,那么就意味着这两天都选择了打比赛,就意味着中间那条边会被割掉。

    但是如果这样,都选择了不打比赛,中间那条边也会被割掉。这样就不对了。所以考虑将中间那条边设为有向边,具体的,就是让黑色点连向白色点。这样再都选择不打比赛时不割中间那条边也不存在一条通路。

    费用流

    【BZOJ 1283】序列

    要点:

    • 将 ”一个区间最多选择 (k) 个“ 视作 ”选 (k) 次,一次一个区间只能选择一个“
    • 不一定非得源点向每一个序列上的点连边,可以顺着连。

    错误:

    • 我开始以为这样建图是可行的:
      • (s) 向序列的每一个数连边,流量为 (1),费用为 (a_i)
      • 用一个点代表一个长度为 (m) 的区间,向终点连流量为 (k) ,费用为 (0) 的边。
      • 每个数向他所属的长度为 (m) 的区间连边,流量为 (1) ,费用为 (0)
    • 但实际上是不对的,因为这样一个数 (a_i) 的流量可以流向其中任何一个包含它的区间,并不是所有被长度为 (m) 的区间包含的数的流量都流到了这个区间到终点的边上,所以可能导致一个区间不止有 (k) 个数。

    题解鸽了。

    【WC2007】剪刀石头布

    要点:

    • 在一条边的流量会不断变化的时候,考虑将这条边拆成好几条边(权值要递增,即前 (i) 条边的权值之和恰好是第 (i) 种变化的权值)
    • 正难则反(计数中,总数减去不符合条件的)主要要想到这样做,怎么做倒是不难。

    记得写清楚为什么这样统计三元环的总数量是正确的(关键在于没有少减掉东西)。

    流量平衡

    鸽了。

  • 相关阅读:
    【5.3】dict的子类
    【5.2】dict的常用方法
    【5.1】dict的abc继承关系
    【4.5】列表推导式、生成器表达式、字典推导式
    【4.4】bisect维护已排序序列
    【4.3】实现可切片的对象
    【4.2】Python序列中+、+=和extend的区别
    【4.1】Python中的序列分类
    【3.12】contextlib简化上下文管理器
    【3.11】Python中的with语句
  • 原文地址:https://www.cnblogs.com/YouthRhythms/p/13420273.html
Copyright © 2011-2022 走看看