最大流:Ford-Fulkerson方法DFS实现

最简单的最大流算法,不断搜索增广路增广。

这是很不划算的算法,因为效率太低了,随便一个数据都能把它卡住。虽然现在10分钟就能打出一个没有错误的SAP,花很长时间搞出这个很不划算。但是,我不能死记一个高级的算法而连最基础的算法都打不出来。竞赛虽然功利,但是学习算法也并不是完全为了竞赛。

在网上找,只能找到几个,因为搞竞赛至少也要用个EK,很少有人做题用DFS的。找到的几个,有的写得太丑了,有的只是给出了过程,反正找不到满意的。因为过程倒是很好理解,自己尝试打了一下,但是调不过去。最后在http://blog.csdn.net/l344431432/article/details/5679106找到了满意的DFS最大流算法实现,模仿着改一下,终于调出来了。另外,这个网址对于那道题的算法描述可能有问题,但代码是对的。

其实DFS最大流和ISAP差不多,或者说ISAP就是它的一种改进,用距离标号来实现寻找最短增光路。而EK是广搜,dinic是构造分层图。代码和ISAP的很像。而且,代码真的很短。

另外,有时候DFS最大流并不是很差,在RQNOJ我的程序跑得比ISAP等理论复杂度更低的算法还快,可能是常数小而且数据友好的原因吧。这个算法还是很看RP的。

代码:

#include <stdio.h>
#define MAXN 300
#define INF 19930317

int c[MAXN][MAXN];
int s, t, i, k, u, v, w, n, m;
int flow, maxflow;
int vis[MAXN];

int dfs(int u, int low)
{
    int i, flow;
    if (u == t)
        return low;
    if (vis[u])
        return 0;
    vis[u] = 1;
    for (i = 1; i <= n; i++)
        if (c[u][i] && (flow = dfs(i, low < c[u][i] ? low : c[u][i])))
        {
            c[u][i] -= flow;
            c[i][u] += flow;
            return flow;
        }
    return 0;
}


int main()
{
    scanf("%d%d", &m, &n);
    for (i = 1; i <= m; i++)
    {
        scanf("%d%d%d", &u, &v, &w);
        c[u][v] += w;
    }
    s = 1;
    t = n;
    while (flow = dfs(s, INF))
    {
        maxflow += flow;
        memset(vis, 0, sizeof(vis));
    }
    printf("%d\n", maxflow);
}

 

多路增广

 

#include <stdio.h>
#define MAXN 300
#define INF 19930317

int c[MAXN][MAXN];
int s, t, i, k, u, v, w, n, m;
int flow, maxflow;
int vis[MAXN];

int dfs(int u, int low)
{
    int i, flow, sum = 0;
    if (u == t)
        return low;
    if (vis[u])
        return 0;
    vis[u] = 1;
    for (i = 1; i <= n; i++)
        if (c[u][i] && (flow = dfs(i, low < c[u][i] ? low : c[u][i])))
        {
            sum += flow;
            low -= flow;
            c[u][i] -= flow;
            c[i][u] += flow;
            if (!low)
                break;
        }
    return sum;
}


int main()
{
    scanf("%d%d", &m, &n);
    for (i = 1; i <= m; i++)
    {
        scanf("%d%d%d", &u, &v, &w);
        c[u][v] += w;
    }
    s = 1;
    t = n;
    while (flow = dfs(s, INF))
    {
        maxflow += flow;
        memset(vis, 0, sizeof(vis));
    }
    printf("%d\n", maxflow);
}

posted on 2011-07-13 12:09  oa414  阅读(1325)  评论(2编辑  收藏  举报

导航