POJ 2391 Ombrophobic Bovines ★(Floyd+二分+拆点+最大流)

题意】有n块草地,一些奶牛在草地上吃草,草地间有m条路,一些草地上有避雨点,每个避雨点能容纳的奶牛是有限的,给出通过每条路的时间,问最少需要多少时间能让所有奶牛进入一个避雨点。 和POJ2112很类似,都是使最大的走过路径长度和最小的题,也是先Floyd再二分求最大流看是否满流……昨天刚做啊,第一下竟然没看出来,真是太年轻太Naive了!……=_= 【思路】拆点建图,每个点的(in)和(out)间容量oo,源点向每个有牛的点(in)连边,容量为该点的牛数,每个有避雨点的点(out)向汇点连边,容量为避雨点能容纳的牛数。然后二分答案做最大流,满流就说明当前值可以让所有牛避雨成功,不断二分缩小答案就ok了。 【为什么要拆点】前几次没有多想,觉得拆点顺理成章的,太主观了,根本没有认真理解……这里要补充一下了: 从两个角度讲。第一,拆点是为了构造二分图,这样才不会出现环从而影响到超级源点到某个“源点”的入流量,如下图所示:   POJ 2391 构图   我们的加边是严格从i->i'的,由此可以看出i节点的入流完全取决于从超级源点来的流,这个流我们设置的是避雨棚当前的人数,这个人数当然从一开始就决定而与其他避雨棚无关且不可改变的。 而如果我们不拆点: POJ 2391   显然1、2、3的节点入流还取决于其他的避雨棚,这显然是不对的。另外,容易想到当前避雨棚人数好避雨棚可容纳人数怎么能放一起呢?显然需要拆点。 第二: POJ 2391   其中每条无向边表示两条方向相反的有向边,容量均为∞。当二分到T = 70的时候,显然我们只加入了(2, 3)和(3, 4)两条无向边,因为只有这两对点间的最短距离小于等于70。但是从图中也可以看出,由于没有拆点,点2也可以通过这两条边到达点4,而实际上这是不允许的。也就是说我们所加的限制条件没有起到作用。 简单的说,这里拆点的作用就是通过拆点加单向边来防止节点的间接连通。 由此可见,只有拆点才是正确的做法。 ============================================================================== 再一个就是吐槽本题数据……略变态…… 【代码http://paste.ubuntu.com/5883013/
posted @ 2013-07-17 12:18  AbandonZHANG  阅读(140)  评论(0编辑  收藏  举报