zoukankan      html  css  js  c++  java
  • 网络流算法基本模型

    网络流最重要的就是模型,下面总结常见的模型

    一、对偶图

    例题:beijing狼抓兔子

    现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,
    而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:
     
    左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 
    1:(x,y)<==>(x+1,y) 
    2:(x,y)<==>(x,y+1) 
    3:(x,y)<==>(x+1,y+1) 
    道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,
    开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击
    这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,
    才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的
    狼的数量要最小。因为狼还要去找喜羊羊麻烦.
    【解】这道题通过观察可以发现,狼王只要保证每条从左上到右下的道路都有狼把守就可以了,而且要尽量少的使用狼(其实就是最小割)。但由于这个题数据范围较大,直接跑会TLE,这个时候就用到对偶图了,总的来说对偶图就是为了解决这类平面图求最小割的问题。观察发现,对于每一条边,必定会有两个面在其左右侧。则我们将左右侧两个面连一条边,且其权值为原来那条边的权值。即对于题图中左上第一个格的斜边,在对偶图中对应的就是一条由1连向2的权值为5的边。然后我们再用对角线的延长线将外部分成两个平面,作为原点和汇点的面。难点就在于对于面的编号,下面给出我在这道题中的建图方法:
     1     for(int i=1;i<=n;i++)
     2         for(int j=1;j<=m-1;j++)
     3         {
     4             scanf("%d",&x);
     5             if(i==1)
     6                 add_edge(j*2,t,x);
     7             else if(i==n)
     8                 add_edge(s,((n-2)*(m-1)+j)*2-1,x);
     9             else
    10                 add_edge(((i-2)*(m-1)+j)*2-1,((i-1)*(m-1)+j)*2,x);
    11         }
    12     for(int i=1;i<=n-1;i++)
    13         for(int j=1;j<=m;j++)
    14         {
    15             scanf("%d",&x);
    16             if(j==1)
    17                 add_edge(s,((i-1)*(m-1)+1)*2-1,x);
    18             else if(j==m)
    19                 add_edge(t,(i*(m-1))*2,x);
    20             else
    21                 add_edge(((i-1)*(m-1)+j)*2-1,((i-1)*(m-1)+j-1)*2,x);
    22         }
    23     for(int i=1;i<=n-1;i++)
    24         for(int j=1;j<=m-1;j++)
    25         {
    26             scanf("%d",&x);
    27             add_edge(((i-1)*(m-1)+j)*2-1,((i-1)*(m-1)+j)*2,x);
    28         }
    二、最大权闭合子图
    例题:noi2006 最大获利(这类模型在noi中考过两次,还有一次是noi2009植物大战僵尸)
    新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战。THU集团旗下的CS&T通讯公司在新一代通讯技术血战的前夜,需要 做太多的准备工作,仅就站址选择一项,就需要完成前期市场研究、站址勘测、最优化等项目。在前期市场调查和站址勘测之后,公司得到了一共N个可以作为通讯 信号中转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第 i个通讯中转站需要的成本为Pi(1≤i≤N)。另外公司调查得出了所有期望中的用户群,一共M个。关于第i个用户群的信息概括为Ai, Bi和Ci:这些用户会使用中转站Ai和中转站Bi进行通讯,公司可以获益Ci。(1≤i≤M, 1≤Ai, Bi≤N) THU集团的CS&T公司可以有选择的建立一些中转站(投入成本),为一些用户提供服务并获得收益(获益之和)。那么如何选择最终建立的中转站才 能让公司的净获利最大呢?(净获利 = 获益之和 - 投入成本之和)
    【解】先将问题转化:现在有一个有向图,每个点有点权,点权可正可负。对于任意一条有向边i和j,选择了点i就必须选择点j,你需要选择一些点使得得到权值最大。 
    这个问题可以用网络流解决。s连到每个用户群vi,权值为Ci,每个中转站ui连到t,权值为花费Pi,原图中<vi, Ai>, <vi, Bi>的权值全部设为INF。 最大权闭合图的的权 = 原图中权值为正的点的和(所有用户的收益之和) - 最小割(最大流)。可以理解为有流量流过的边都被割掉了,也就是我们得不到他们的收益了(对于通信站就是我们得花钱去建了),因为最大流是最小割,显然我们割掉的越少越好,所以求最大流,再用可能得到的总收
    入减去就好了。
    三、求最小割点集
    例题:洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication
    农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流。这些机器用如下的方式发送电邮:如果存在一个由c台电脑组成的序列a1,a2,...,a(c),且a1与a2相连,a2与a3相连,等等,那么电脑a1和a(c)就可以互发电邮。很不幸,有时候奶牛会不小心踩到电脑上,农夫约翰的车也可能碾过电脑,这台倒霉的电脑就会坏掉。这意味着这台电脑不能再发送电邮了,于是与这台电脑相关的连接也就不可用了。有两头奶牛就想:如果我们两个不能互发电邮,至少需要坏掉多少台电脑呢?请编写一个程序为她们计算这个最小值。以如下网络为例:1*/ 3 - 2*这张图画的是有2条连接的3台电脑。我们想要在电脑1和2之间传送信息。电脑1与3、2与3直接连通。如果电脑3坏了,电脑1与2便不能互发信息了。
    【解】很明显,我们要求的就是最少要割掉多少个点,所以可以转化成拆点法求最小点割集(最大流最小割定理应用):先把每个点i拆成两个点,编号分别为i和i+n,把i到i+n连一条容量为1的边,然后若i到j有一条边,则连接i+n->j,i->j+n,边权为无穷大,然后求s+n到t的最大流即是答案。
    四、二分图模型
    例题:zjoi2009假期的宿舍
    学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题。比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识。我们假设每个人只能睡和自己直接认识的人的床。那么一个解决方案就是 B 睡 A 的床而 C 睡 B 的床。而实际情况可能非常复杂,有的人可能认识好多在校学生,在校学生之间也不一定都互相认识。我们已知一共有 n 个人,并且知道其中每个人是不是本校学生,也知道每个本校学生是否回家。问是否存在一个方案使得所有不回家的本校学生和来看他们的其他人都有地方住。
    【解】经典的二分图,我们只要把学生和原点连接,然后学生和能住的床连接,床在和汇点连,这样跑最大流也就是答案了,改图的最大匹配就是最多有多少人可以有床睡。
     
    玲珑骰子安红豆,入骨相思知不知。
  • 相关阅读:
    LINUX_bash
    【c++】必须在类初始化列表中初始化的几种情况
    Hadoop 学习笔记 (八) hadoop2.2.0 测试环境部署 及两种启动方式
    hadoop各版本下载
    mapreduce (六) MapReduce实现去重 NullWritable的使用
    hadoop 生态系统版本对应问题
    mapreduce (五) MapReduce实现倒排索引 修改版 combiner是把同一个机器上的多个map的结果先聚合一次
    mapreduce (四) MapReduce实现Grep+sort
    ctr预估模型
    mapreduce (七) 几个实例
  • 原文地址:https://www.cnblogs.com/hyl2000/p/6618519.html
Copyright © 2011-2022 走看看