网络流Dinic算法详解及模板

/*****以下来自<<浅谈基于分层思想的网络流算法>> 王欣*****/

层次图




短路增值算法(MPLA)

算法流程

网络流Dinic算法详解及模板_第1张图片

汇点不在层次图内意味着在剩余图中不存在一条从源点到汇点的路径,即没有增广路。

在程序实现的时候,层次图并不用被“建”出来,我们只需对每个顶点标记层次,增广的时候,判断边是否满足level(u) +1= level(v)这一约束即可。

Dinic算法

Dinic算法的思想也是分阶段地在层次图中增广。

它与最短路径增值算法不同之处是:在Dinic算法中,我们用一个dfs过程代替多次bfs来寻找阻塞流。下面给出其算法步骤:

算法流程

网络流Dinic算法详解及模板_第2张图片

增广过程图解

网络流Dinic算法详解及模板_第3张图片

网络流Dinic算法详解及模板_第4张图片

伪代码描述

网络流Dinic算法详解及模板_第5张图片

在程序里,p表示找到的增广路径,p.top为路径中的最后一个顶点。一开始,p中只有源点。
整个While循环分为2个操作。如果p的最后一个顶点为汇点,也就是说找到了增广路,那么对p增广,注意到增广后一定有一条或多条p中的边被删除了。这时,我们使增广路径后退至p中从源点可到达的最后一个顶点。
如果p的最后一个顶点不为汇点,那么观察最后那个的顶点u 。若在层次图中存在从u连出的一条边,比如(u,v),我们就将顶点v放入路径p中,继续dfs遍历;否则,点u对之后的dfs遍历就没有用了,我们将点u以及层次图中连到u的所有边删除,并且在p中后退一个点。
Dfs过程将会不断重复这2个操作,直到从源点连出的边全部被删除为止。

/*****以上来自<<浅谈基于分层思想的网络流算法>> 王欣*****/

模板

/* filename :network_flow_Dinic.cpp
 * author :AntiheroChen
 * Description :It's a Dinic solution for the network flow prblem.
 * Complexity :O(V^2*E) always below this.
 * Version :1.00
 * History :
 * 1)2012/02/29 first release.
 */
#include 
#include 
#include 
#include 
using namespace std;
const int maxn=1000+5, bign=1000000000;
int M, n, m, source, sink, c[maxn][maxn], cnt[maxn];


/* The arc of the flow network.*/
struct Pool
{
    int next, t, c;
} edge[maxn*maxn<<1];


/* The point of the flow network.*/
struct Point
{
    int son, cur, pre, lim, d;
} a[maxn];


/* Prepare for the algorithm.*/
void initialize()
{
    M=1;
    memset(c, 0, sizeof (c));
    memset(a, 0, sizeof (a));
    memset(cnt, 0, sizeof (cnt));
}


/* Add an arc to the flow network.*/
void add(int x, int y, int z)
{
    edge[++M].t=y;
    edge[M].c=z;
    edge[M].next=a[x].son;//相当于pool的head数组
    a[x].son=M;
}


/* Read the data and make it the right format.*/
void input()
{
    scanf("%*s%*d%d%d%d%d", &n, &m, &source, &sink);
    initialize();
    int x, y, z;
    while (m--)
        scanf("%d%d%d", &x, &y, &z), c[x][y]+=z;
    for (int i=0; i


你可能感兴趣的:(图论)