题目:
https://jzoj.net/junior/#main/show/1301
这道题题目大意有点难理解,看下图:
题目其实是要指从水潭(起始点1)到小溪(终点n)的最大排水容量.
这个排水容量是指当前所有能往小溪灌水的点能灌到的最优水量.
计算样例:从水潭开始,先往小溪灌20水量,然后再往第2个交点灌40水量,然后从第2个交点又可以往小溪灌20水量,又可以再往第3个交点灌10水量,然后最后,第3个交点其实有20水量(40-20=20)可以往小溪灌10水量。所以,小溪所能获得的最大值就是20+20+10=50水量。
具体方法如下:
如题所述图为有向图,并且因为这个图之间的两两交点之间可能不止一条边,所以我们需把两点容量值累加.
我们从第一个点出发,然后把与1可以相关联的所有边都拓展一遍,怎么拓展呢?
第一个点的最优水量值我们可以设置为Maxlongint,因为可视水潭容量无限.
于是我们把所有点都枚举一遍,然后,我们可以弄一个数组a表示当前第1个节点到第i个节点的最大容量.
每次需要扩展边的时候,就取一个“原点本身拥有的最优水量”(即a[tot])与“原点与拓展点之间的流量”的较小值作为从原点到拓展点的“最优水量”(即a[i])。
如果这个“最优水量”大于拓展点原来的最优水量,则更新拓展点的最优水量。
然后在水潭‘1’拓展完之后,找一个a数组里所表示的最优水量的最大值,且这个最大值所对应的点在一条路径中没有被选过才可以选择,而后以这个最大值所对应的点作为下一个往下拓展的点,以此类推...
直至拓展点为m的时候.
我们可以明白,当拓展点为m的时候,则表示了当前选择的一条流法已经所有可能的流法当中条最优的一条流法了.
所以,为了下次继续这种流法,我们需要把这条流法的路径上的所有边的流量都减去a[m],至于为什么自己想想.
但,我们还需把这条流法路径上所有边的倒边的流量都加上a[m](通俗的说就是如果原来把f[x,y]减去a[m],则还需把f[y,x]加上a[m])但这是为什么呢?
例:从1开始,可以从1->2->3->6这样一条最优的流法,把答案累加10000后,把1->2,2->3,3->6的路径值都减去10000.然而还需把2->1,3->2,6->3都加上10000,这是因为题目中描述了这是一个环形流动的水池,也就是除了上面路径,还可以通过1->4->3->2->5->6(但是却不能在输入的时候直接把图变成一个所谓“环形流动”的水池,理由是会死循环)
而当没有可能拓展的点时就可以直接输出并结束程序了.