一些经常使用的套路:网络
发现天天开始和结束时的状态是不同的,考虑拆点。spa
接着怎么办?模拟餐巾的路线吗?设计
假如从白天向晚上连一条边表示餐巾由干净变为脏的话,会发现根本没法处理天天的需求量。递归
那反正只要是干净的就好了,咋来的咱无论,那就直接从超级源点流过来嘛。而后就可让餐巾流到超级汇点来完成需求啦!get
具体分如下几种:it
而后跑最小费用最大流。io
值得注意的是,第三点处于贪心的考虑,确定会直接洗掉。但咱们发现设计的方案中并无设置这样一个库存餐巾,因此就得经过这一步来使得餐巾可以在必须洗的那天晚上恰好洗掉,从而达到和提早洗完同样的效果。因此若是某天晚上就算送去快洗也洗不完了,前一天晚上的这条边能够不连。class
乱翻网络流二十四题时有幸看到这个帖子。秒杀
故在此说明一点:最长路径问题是 NP-HARD 的缘由是可能存在正权圈,这种状况下要求最长简单路径。相似地,存在负权圈的最短简单路径也是 NP-HARD 的。详情能够看这个回答。di
每一个仓库向每一个零售商店连容量为 \(\infty\),给定费用的边。再从超级源点向每一个仓库连容量为给定数量,费用为 \(0\) 的边;从每一个零售商店向超级源点连容量为给定数量,费用为 \(0\) 的边,最后跑最大费用最大流。直接将权值取反而后再跑一遍最小费用最大流便可,记得跑完一遍后记得重置每条边当前流量。
其实这种简单题的建模不难,对着题意模拟,把每种可能的状况考虑进去就好了。
若是理解了最上面三条东西能够秒杀。
路径互不相交说明啥?点不能重复选呗,那就拆点而后两点之间连容量为 \(1\) 的边。
路径仅容许在数字结点处相交说明啥?边不能重复选,点能够重复选呗,那就两点之间容量搞成 \(\infty\),从上一层走到下一层的边容量搞成 \(1\)(容易发现上一种状况这里设成大于 \(1\) 的均可行)。
路径随便相交怎么办?除了从超级源点到最上面的 \(m\) 个点容量设为 \(1\) 外其它容量所有 \(\infty\) 呗。
神仙题,真的神仙。
依次塞球,若是塞不下了就加一根柱子,直到柱子不够为止。
那么具体咋建图呢?依旧考虑拆点,但拆点的做用有所不一样,这里仅仅是为了方便处理,将每一个球拆成出球(叠在一个球上面)和入球(一个球叠在它上面)。
从超级源点向每一个入球连容量为 \(1\) 的边,从每一个出球向超级汇点连容量为 \(1\) 的边。再从每对合法的较小的入球向较大的出球连边。
能够发现,从超级源点到超级汇点最长只存在长度为 \(3\) 的正向路径!举个栗子:\(S\to in_1\to out_3\to T\)。
但这样刚好表明了一个球的堆叠!接下来:\(S\to in_3\to out_6\)。
这样就堆叠了两个球!因此就这样每次新加一个球,若是最大流没有增长,说明须要一根新的柱子。
接着来考虑第二问:怎么找方案?
好像把全部路径撸出来而后重组一下是可行的,但这里给一种普适性不好的作法(显然本题流量仅有 \(0\) 和 \(1\))。
考虑一条正向边,若是它被选了,那么流量必定为 \(1\)。DFS 下去,遇到这样的边而且出点尚未用过,就把流量置为 \(1\) 而后继续递归下去。
从超级汇点到入球都没有问题,到出球时直接输出。
至于正确性嘛,流量为 \(1\) 的边确定是流满的嘛,那还能咋流呢?不可能出现两条同时流满的边嘛。
黑白染色,由相邻的黑点向白点连容量为 \(\infty\) 的边。
黑点接到超级源点上,白点接到超级汇点上,权值为对应的数。
想要合法,无非就是一些点不选。显然中间的边是不会去删的,只会删两边的边。求出最小割(不连通说明合法)而后拿总权值减一下就行了。