版权声明:本文为CSDN博主「winter2121」的原创文章,遵循CC 4.0 BY-SA版权协议。
原文链接:https://blog.csdn.net/winter2121/article/details/80076806
————————————————————————————————————
闭合图:对于一个有向图G,存在点集合V,任取点u属于V,u的出边的另一个点也属于V,则为闭合图。
理解:任取一起点,终点必定是无出度的点。
最大权闭合子图:当每个点有一个权值w(有正有负),点权和最大的闭合图为最大权闭合子图。
求解方法:网络流。
建立超级源点s,超级汇点t。
所有点权为正数的点i,建边 s->i,容量为点权。
所有点权为负数的点i,建边i->t,容量为点权绝对值。
原图建图后,边容量均为正无穷。
最大权闭合图的权值 = 正权点之和 - (s->t)最大流
证明:
源点s可以理解为最大可获得的权值(即正权点之和)
汇点t可以理解为最大的会损失的权值(负权点之和)
我们现在要尽量的获得s,而避免t。
然而要想选出一个最大权闭合图,选定一个点,那么这个点的所有后继子孙点,都必须选择。
因此,想拿正数,就不可避免的要取负数子孙后继点(当然子孙点是正数最好了)。
所以我们尽量选择正权点为起点,才有可能增大闭合图点集的权值和,因此我们从源点s向正权点连边(即只以正权点为起点)。
至于过程中遇到的负权点,我们让其流向t,即建立边 负权点->t的意图。
好,现在我们尽量去取正数点(直接从源点s起始),过程中遇到的负权点流向t。
现在就变成了:s->t的流量就是我们的损失。
即我们希望流向t的流量flow尽量少,而从s流出的流量sum尽量多,从s流出而没有流入t的流量(sum-flow)就是闭合图的最大权。
可能有种情况很懵逼:
若要选点,选2吧,权为-5,选1和2吧,权为-1,如果选个空点集,权为0。明显最后的选择是对的。
按照上面的思路,从s流出4,所以损失最多为4,sum-flow=0。
所以对该图就产生这么一种结论:
我选择那个1号点,和不选那个1号点,结果是相同的,我选的时候他会被损失完而已,效果等同于不选。
那不妨我一开始就把所有的正权点都给选了(满足从s流出的最多),让他们往后代流,大不了被负权子孙点损失完,而那些没有被损失完的,就是我们统计下来的结果。
那个损失,就是s->t的最大流。
得证:闭合图最大权 = 正权和sum - 最大流flow