Edmonds-Karp algorithm

코드

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX_V 55

using namespace std;

struct Edge {
    int to, c, f;
    Edge *r;
    Edge(): Edge(-1, 0) {}
    Edge(int _to, int _c) : to(_to), c(_c), f(0), r(NULL) {}
    int spare() {
        return c - f;
    }
    void addFlow(int _f) {
        f += _f;
        r->f -= _f;
    }
};

int ctoi(char c) {
    if (c >= 'a') return c - 'a';
    else return c - 'A' + 26;
}

int main()
{
    int n, total = 0;
    vector<Edge*> adj[MAX_V];

    scanf("%d", &n);
    while (n--) {
        char u, v;
        int w, uu, vv;
        scanf(" %c %c %d", &u, &v, &w);
        uu = ctoi(u);
        vv = ctoi(v);
        Edge *e1 = new Edge(vv, w), *e2 = new Edge(uu, w);
        e1->r = e2;
        e2->r = e1;
        adj[uu].push_back(e1);
        adj[vv].push_back(e2);
    }

    while (1) {
        int prev[MAX_V], S = ctoi('A'), E = ctoi('Z');
        Edge *path[MAX_V] = { 0 };
        fill(prev, prev + MAX_V, -1);
        queue<int> q;

        q.push(S);
        while (!q.empty() && prev[E] == -1) {
            int v = q.front();
            q.pop();

            for (Edge *e : adj[v]) {
                int next = e->to;
                if (e->spare() > 0 && prev[next] == -1) {
                    q.push(next);
                    prev[next] = v;
                    path[next] = e;
                    if (next == E)
                        break;
                }
            }
        }

        if (prev[E] == -1)
            break;

        int flow = 1e9;
        for (int i = E; i != S; i = prev[i])
            flow = min(flow, path[i]->spare());
        for (int i = E; i != S; i = prev[i])
            path[i]->addFlow(flow);

        total += flow;
    }

    printf("%d", total);

    return 0;
}

https://www.acmicpc.net/problem/6086 에 대한 풀이

코드 템플릿 (C++11)

#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>
#define MAX_V 2100

using namespace std;

struct Edge {
    int to, c, f;
    Edge *r;
    Edge() : Edge(-1, 0) {}
    Edge(int _to, int _c) : to(_to), c(_c), f(0), r(NULL) {}
    void addFlow(int _f) {
        f += _f;
        r->f -= _f;
    }
    int spare() {
        return c - f;
    }
};

vector<Edge*> adj[MAX_V];

void insertEdge(int u, int v, int w) {
    Edge *e1 = new Edge(v, w), *e2 = new Edge(u, 0);
    e1->r = e2;
    e2->r = e1;
    adj[u].push_back(e1);
    adj[v].push_back(e2);
}

int main()
{
    // ...

    int S = 0, E = 2, result = 0;
    while (1) {
        queue<int> q;
        int prev[MAX_V];
        Edge *path[MAX_V] = { 0 };

        fill(prev, prev + MAX_V, -1);

        q.push(S);
        while (!q.empty() && prev[E] == -1) {
            int v = q.front();
            q.pop();

            for (Edge *e : adj[v]) {
                int next = e->to;
                if (e->spare() > 0 && prev[next] == -1) {
                    q.push(next);
                    prev[next] = v;
                    path[next] = e;
                    if (next == E)
                        break;
                }
            }
        }

        if (prev[E] == -1)
            break;

        int flow = 1e9;
        for (i = E; i != S; i = prev[i])
            flow = min(flow, path[i]->spare());
        for (i = E; i != S; i = prev[i])
            path[i]->addFlow(flow);

        result += flow;
    }

    // ...
}

정리

  • Ford Fulkerson 의 BFS 버전, 시간복잡도는 O(VE^2) 이다.

관련문제

참고자료

results matching ""

    No results matching ""