这周看了一下网络流的有关内容,因为害怕直接复习以前的知识自己又会偷懒,直接奔了个比较难的知识点。
网络流这块知识并不是太好理解,但也不能说很难理解。通俗的来讲,从源点到汇点的一些带权边所构成的网络,其中流量受到通过边的最小流量的限制(就这一个方面来讲,有点类似于平时上网时候传输网络的网速一样,经过很多中转站,但最终得到的最大网速和中间最小的边权有关系。)在网络流中,有两个重要的概念,一个是残留网络,一个是增广路,残留网络就是可以容纳更多流的边,而增广路就是从所有的残留网络中存在的从源点到汇点的一条通路。
这周前几天主要看了有关于网络流的最大流的前两个算法,一个EK,一个SAP。EK算法是最大流里面最好理解的一个算法,思路就是用bfs寻找增广路,然后对增广路的最小边进行查询,用最小边的边对整个路径进行更新,并更新最大流的数值,知道无法找到增广路。这个算法十分好理解,但是时间复杂度也是十分的高的(因为用了bfs)。SAP算法对找增广路的方法进行了优化。这种算法的核心是距离标号,比较不好理解,尤其是GAP记录优化。其算法就根据距离标号是找可行弧,沿着可行弧寻找增广路。若寻找至终点,沿着可行弧对整个路径进行一次简单更新(这里留下一个疑问,书上的代码是返回的瓶颈边进行下一步的搜索,而网上的代码多是返回源点,哪一个更优我觉得都有道理。)。若找不到,更新GAP记录,若为0,表示出现断层(也就是没有可以到达终点的边),也就是完成了查找,反之找到最小的标号,使得起点的标号=最小标号加一,而后返回上一个折点继续进行查找。
由于书上的代码模板没有主函数,不利于理解每个数组存了什么,于是又拿出饶齐的博客翻看一番,他用的是最大流的第三个算法DIC解题,所以没怎么看具体实现,主要看怎么建立网络流,怎么存边。发现题目并不像自己所想的那样简单明了,并非直接给你一个网络,让你去实现最大流的求算,而是让你自己去建立一个网络流,而后自己求算其中的最大流。比如:Task Schedule
这个题目的大致意思就是M台机器,N个工件分别对应着开始日期,最晚结束日期,以及所需要的时间。对于这个题目,建立网络流源点到任务有边,任务到可行日期右边,可行日期到汇点有边,只有最大流的数值刚好达到了所有工作的完成日期的和才说明存在一个路径使得该任务可以完成。
又比如:Dining
这个题目的题意是牛有喜欢的饮料和食物,现有食物饮料,问能否满足所有的牛。这个题目和上面的题目有一些类似之处,求的是可行路径个数,只需要让所有条件之间存在连边,最终求最大流的数量即可。
这些题目的千奇百怪,但也并无规律可循,往后的几天看看DIC,并加强题目,并试做一些题目。