「总结」网络流
Posted lrefrain
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「总结」网络流相关的知识,希望对你有一定的参考价值。
网络流专题,总结一下。
一、最大流
一个网络图的最大流量,满足网络流的各种性质的情况下。
1.蜥蜴
简单的拆点,在点之间限流即可,设有$a_i$的高度,从$S$向有蜥蜴的柱子$x$连边,边缘的柱子向$T$连边,距离小于$i,j$。
$$link(S,x,1),link(i_0,i_1,a_i),link(j,T,INF),link(i,j,INF)$$
跑最大流就可以了。
2.
二、最小割
三、最大权闭合子图
根据最小割的模型,我们建立另外一个模型,关于物品是否被选择的模型。
对于一个物品来说,选择存在某种收益。如果这个收益是正值,我们建边$S->i|a_i$,并在答案中累加$a_i$,如果是负权则不累加并连边$i->T|a_i$。
具体来说大概长这样:
如果一个物品在一种方案中被选择我们就隔断他链接$S$的边,否则是$T$的。
当然了,$S$和$T$可以根据不同的需要调换位置。
1.最大获利
对于每一个请求拆出一个点来。
对于每个询问$p$来说建图为:
$$link(S,p,c_p),link(p,A_p,INF),link(p,B_p,INF),link(A_p,T,w_{A_p}),link(B_p,T,w_{B_p})$$
也就是利用了$INF$边不可割断的特性,强制选择两方面之一。
2.$happiness$
对于每两个人的关系拆出两个点来。
设两个点分别为$i,j$,拆出两个点为$l,r$,他们单独选文/理的贡献是$a_i/b_i$,共同选文/理的贡献是$c_{i,j},d_{i,j}$
这样规定割$S$这边代表选文,割$T$代表选理。
那么这样建图:
$$link(S,i,b_i),link(S,j,b_j),link(i,T,a_i),link(j,T,a_j),link(S,l,d_{i,j}),link(r,T,c_{i,j})$$
这样相当于规定了每种情况的贡献,紧接着体现这些情况间的关系。
$$link(l,i,INF),link(l,j,INF),link(i,r,INF),link(j,r,INF)$$
这样就强制了四种情况对于两个人之间关系的处理方式。
两个都选文的情况下,必须要割掉$S->l$这样就去除了两个人都选理的贡献,反之则需要割掉$r->T$,这样就去掉了两个人都选文的贡献。
一个选文一个选理的情况下,由于$INF$边的强制要求,这两条边都必须要割掉,那么就把他们都割掉,这样也是对的。因为两个人之间的贡献一个也不能有。
这道题最难的地方在于综合利用拆点技术和$INF$边来共同体现每种情况之间的联系,从而达到各个情况的取值的正确。
3.$employ$人员雇佣
设一对人员关系为 $i,j$,我们发现,如果两个人都被雇佣,才能收到额外收益,否则不仅拿不到额外收益,而且还要减掉一定的额外收益。
我们设一个人的权值$w_i=sumlimits_{k=1}^{n}E_{i,k}$代表他所能给其他人带来的贡献。
那么这样建图:
$$link(S,i,a_i),link(S,j,a_j),link(i,T,w_i),link(j,T,w_j)$$
这样规定每个点的权值,割$S$代表雇佣,割$T$代表不雇用。
可以发现这样是对的,然后体现两个人之间的关系,由于当一个人选一个人不选的情况下,会造成额外的负担,那么接着建边。
$$link(i,j,E_{i,j}),link(j,i,E{j,i})$$
这样当一个人选一个人不选的时候,就必然要割掉$i,j$间的一条边,从而体现$i,j$之间的互相影响这一条规定。
这道题的难点在于区分统计两个人之间的关系和自身属性,另外还有模型转化方面。
4.线性代数
看起来让人一脸懵,查了查什么是矩阵转置才会做,难点在题意转化上面,$A$是$0/1$矩阵,可以看到最大权闭合子图的影子。
设$G=AB$发现$G$的本质就是,对于$B$的每一行都按照$A$的$0/1$情况来累加到$G$的对应位置上。
原本的矩阵乘法是$A$的行乘上$B$的列,那我们这样区分计算贡献,就变成了上面那种情况。
还要减掉一个$C$,然后在乘上$A^T$。
区分两部分计算。
$(AB-C)A^T=ABA^T-CA^T$
发现左边的部分的贡献其实就是行列向量相乘,而且还是$0/1$的形式。
这样就方便的转化这一部分的贡献,对于$B$上面的每一个位置$B_{i,j}$,我们规定在$A$上的两个位置$A_i,A_j$均为$1$的时候我们才可以拿到这部分贡献。
在看看后面的部分,当$A_i$是1的时候,我们要付出$C_i$的代价。
设$w_i=sumlimits_{k=1}^{n}B_{i,k}$
那么这样建图:
$$link(S,i,w_i),link(S,j,w_j),link(i,T,C_i),link(j,T,C_j)$$
那么$S$边视为选0,$T$边视为选$1$。权值固定了,着手关系体现。
$$link(i,j,B_{i,j}),link(j,i,B_{j,i})$$
这样如果是一个为0一个为1的情况我们必然要割掉一条边,这样符合两个都选才能获得贡献的规定,而如果都选或者都不选,都不会割掉这两条边,单用第一层建图的方式仍然是正确的。
难点在于题意转化,将矩阵乘法关系转化为布尔运算关系,转化完了和人员雇佣几乎一样了,破题想了一天。。结果还是我线性代数太差了的缘故。
5.植物大战僵尸
相对于之前的几道题还是要简单一点。毕竟是十年前的题了。
学长讲过一次,没怎么听懂。
其实就是一些限制关系,如果一个点没有被破坏,那么另外一个受他控制的点也不能被破坏。
那么如果两个点$i,j$之间存在控制关系,建立$i-->j|INF$的边。对于必须从右往左破坏的限制,我们从左边的点向它临接的右边的点建立$INF$边
首先来一次$INF$边的$topsort$去掉环上的点。
这些点的贡献不可能被计算。
对于一个正权点:$link(S,i,a_i)$
否则:$link(i,T,-a_i)$
这样联通$INF$一起跑网络流就可以了。
难点在于去掉那些环上的点,可以发现不去掉根本做不了。
6.寿司餐厅
前天晚上睡不着想了一晚上就会了。
其实不是特别简单的一道题了,可以说我刷的里面的难度巅峰了。
不过很庆幸还是想出来了。
一开始想的是能否和人员雇佣一样,将子区间的贡献累加成大区间的权值,直到我想明白了一个性质。
对于一个区间来说,如果某种方案选择了这个区间,那么在强制选择这个区间的方案中最优秀的那些方案比然不会选择其子区间。
很好理解,可能出现正贡献的只有那些$d_{i,j}$,而如果选择了一个区间之后,可以发现再选择其子区间只能出现负贡献而不会出现正贡献。
那么这种选择就是不优的。
这样就可以简单了。
因为子区间不会被选择的性质,我们发现一个位置寿司最多被吃一次。
那么对于每一种寿司都建立一个新点,从代表最小的区间$[i,i]$的点向他们连$INF$边,这样可以保证如果某一个点是选择的(从$S$来的边没有被隔断),必然有一条流是通过$INF$的,我们再从这个新点向$T$连边,边权为$ma_i^2$,这样就可以体现代价中的一部分,注意到代价有另外一部分,跟每种寿司被吃的个数有关,这种贡献从最小区间代表的点链接向$T$即可,这样每次选择一个点,我们必须吃他连接向$T$的点,这样边权设置为$a_i$即可,保证吃一次就做编号大小的贡献。
我们不再像人员雇佣那样将一个人的贡献全部都累加到一起,因为我们发现因为区间的记忆性质,是不可能以一个区间的选择有无来判断其子区间是否做贡献。
那么这个区间的权值就定为他自身的综合美味度,由于其子区间不可能再次被选,可以认为选择了一个大区间就要强制其子区间被选择,那么从一个大区间向子区间连$INF$边即可。
可是这样建图是$1e8$级别的边数。
考虑到一个点如果控制子区间的子区间,其实只需要控制其子区间即可。那么直接从一个点向比他长度小1的子区间连边即可,边就是二叉树$O(n)$级别的了。
这个题很难。难点很多,主要在于性质的发现和边数的优化方面。
以上是关于「总结」网络流的主要内容,如果未能解决你的问题,请参考以下文章
C#流总结(文件流内存流网络流BufferedStreamStreamReader/StreamWriterTextReader/TextWriter)