网络最大流模板(Edmonds-Karp算法)

测试模板能不能过的——————题目链接

邻接矩阵存图

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

const int inf = 0x3f3f3f3f;
const int maxn = 10050;
using namespace std;
int n, m;
int s, t;
int maps[maxn][maxn], pre[maxn], flow[maxn], maxflow;
//maps 邻接矩阵 pre[i] 记录增广路上的i点的前一个点 flow[i]表示从源点到该点的增广路上的可改进量


int bfs()//用bfs去找增广路
{
    queue <int> q;
    while(!q.empty())
        q.pop();
    for(int i=0; i<=n; i++)
        pre[i] = -1;
    pre[s] = 0;
    flow[s] = inf;
    q.push(s);
    while(!q.empty()){
        int x = q.front();
        q.pop();
        if(x == t)
            break;
        for(int i=1; i<=n; i++){
            if(maps[x][i]>0 && pre[i]==-1){
                q.push(i);
                pre[i] = x;//记录前置点
                flow[i] = min(flow[x], maps[x][i]);//更新可改进量
            }
        }
    }
    if(pre[t] == -1)
        return -1;
    return flow[t];
}

void EK(){
    int a = bfs();
    while(a!=-1)//是否有增广路
    {
        //printf("%d****
", a);
        int k = t;
        while(k != s){
            int last = pre[k];
            //这里是一条 点last ---> 点k 的边
            maps[last][k] -= a;//前向弧
            maps[k][last] += a;//后向弧
            k = last;
        }
        maxflow += a;
        a = bfs();
    }
}

int main()
{
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for(int i=0; i<m; i++){
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        maps[a][b] += w;
    }
    EK();
    printf("%d
", maxflow);
    return 0;
}

邻接矩阵存图,只拿到了70分,有三个点MLE了
不过这个还是很好写的



邻接表(链式前向星实现)

#include <bits/stdc++.h>
const int maxn = 10050;
const int inf = 0x3f3f3f3f;
using namespace std;
struct note{
    int u, v, w;
    int next;
}e[maxn*20];	//边数开大点
int head[maxn], cnt;
int pre[maxn], vis[maxn];
//pre[i] 记录的是增广路上的i点的前一条边在的e数组中的位置
int n, m, s, t;

void add(int u, int v, int w){
    e[cnt].u = u, e[cnt].v = v, e[cnt].w = w;
    e[cnt].next = head[u], head[u] = cnt++;
	//建边建两条,是不是很像残留网络
    e[cnt].u = v, e[cnt].v = u, e[cnt].w = 0;
    e[cnt].next = head[v], head[v] = cnt++;
}

bool bfs(){//找增广路
    queue <int> q;
    memset(pre, -1, sizeof(pre));
    memset(vis, false, sizeof(vis));
    vis[s] = true;
    q.push(s);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int i=head[u]; ~i; i=e[i].next){
            int v = e[i].v;
            if(e[i].w>0 && !vis[v]){
                pre[v] = i;
                vis[v] = true;
                if(v == t)//找到
                    return true;
                q.push(v);
            }
        }
    }
    return false;

}

void EK()
{
    int maxflow = 0;
    int a;
    while(bfs()){
        a = inf;
        int i = pre[t];
        while(~i){	//找适合的增量
            a = min(a, e[i].w);
            i = pre[e[i].u];
        }
        i = pre[t];
        while(~i){
            e[i].w -= a;	//想象下残留网络
            e[i^1].w += a;
            i = pre[e[i].u];
        }
        maxflow += a;
    }
    printf("%d
", maxflow);
}

int main()
{
    memset(head, -1, sizeof(head));
    cnt = 0;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    for(int i=0; i<m; i++){
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        add(a, b, w);
    }
    EK();
    return 0;
}

原文地址:https://www.cnblogs.com/jizhihong/p/13337359.html