[图论]最大流介绍 Ford-Fulkerson算法 邻接表实现

来源:互联网 发布:java 垃圾评论过滤 编辑:程序博客网 时间:2024/05/29 09:37

这次来讲最大流的相关问题,介绍图上的网络流。网络流具有各种各样的性质和应用,还有很多的变体,程序设计竞赛当中也经常会出现相关题目。

先来看一个例子:

最大传输量
网络中有两台计算机st,现在想从s传输到t,该网络中一共有N台计算机,其中一些计算机之间连有一条单项的通信电缆,每条通信电缆都有对应的1秒钟所能传输的最大数据量。当其他计算机之间没有数据传输时,在1s内最多可以传输多少数据到t

这里写图片描述

把计算机当作顶点,把链接计算机的通信电缆当作边,就可以把这个网络当作一个有向图来考虑了。图中的每条边eE,都有对应的最大可能的数据传输量c(e),这样,就可以把问题转为如下形式。

  • 记录每条边对应的实际数据传输量为f(e)
  • 传输量应该满足如下限制:
    0f(e)c(e)
  • 对任意 v{s,t} 都有 Σeξ(v)f(e)=Σeξ+(v)f(e),即数据在传输过程中既不会增加也不会减少,收到的量和发出去的量必须相等。
  • 目标是最大化从s发出的数据量Σeξ+(s)f(e)
    我们称是的传输量最大的f为最大流,而求解最大流的问题称为最大流问题。此外, 我们称c为边的容量,f为边的流量,s为源点,t为汇点。那么,这个问题应该如何求解呢?首先考虑下面的贪心算法。
    1、找一条st的只经过f(e)<c(e) 的边的路径。
    2、如果不存在满足条件的路径,则结束算法,否则,沿着该路径尽可能地增加c(e),返回第一步。
    将该算法运用于样例,就得到了如下结果:

这里写图片描述

这样的结果是正确的吗?事实上,如果采用以下的方案,可以得到更优的结果。显然这个贪心算法是不正确的。

这里写图片描述

我们观察两者之间的流量之差,可以发现,后者的方案在1->2之间少了1Mbps,却换来了s->2和1->3->5两处的流量增加。事实上,就是将原先得到的流给退回去,从而得到了新的更大的流,将算法进行如下改进:
1、只利用满足f(e)<c(e)e 对应的反向边 rev(e) ,寻找一条从 st 的路径。
2、如果不存在满足条件的路径,则结束,否则,沿着该路径尽可能地增加流,返回第一步。

struct edge{int to,cap,rev;};//终点、容量、反向边vector<edge> G[MAXV];//邻接表bool used[MAXV]; //dfs时要用到//向图中增加一条从s到t,容量为cap的边void add_edge(int from,int to,int cap){    edge temp;    temp.to = to;    temp.cap = cap;    temp.rev = G[to].size();    G[from].push_back(temp);    temp.to = from;    temp.cap = 0,    temp.rev = G[from].size()-1;    G[to].push_back(temp);}int dfs(int v,int t,int f){    if (v==t) return f;    used[v] = true;    for(int i = 0; i < G[v].size(); i++)    {        edge &e = G[v][i];        if (!used[e.to] && e.cap > 0)        {            int d = dfs(e.to, t, min(f,e.cap));            if (d>0)            {                e.cap -= d;                G[e.to][e.rev].cap += d;                return d;            }        }    }    return 0;}int max_flow(int s,int t){    int flow = 0;    for(;;)    {        memset(used,0,sizeof(used));        int f = dfs(s,t,INF);        if (f==0) return flow;        flow += f;    }}

记最大流的流量为F,那么Ford-Fulkerson算法最多进行F次深度优先搜索,所以其复杂度为O(F|E|)。不过,这是一个很松的上界,达到这种最坏复杂度的情况几乎不存在。所以在多数情况下,即便通过估算得到的复杂度偏高,实际运用当中还是比较快的。

0 0