您的位置:首页 > 理论基础 > 计算机网络

网络流---EK模版

2015-08-02 09:33 447 查看
EK算法就是不断的从源点到汇点找增光路进行增广

第一种:书上的模版

[code]#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define N 1010
#define INF 0x3f3f3f3f

struct Edge{
    int from, to, cap, flow;
    Edge() {}
    Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow){}
};

struct EK{
    vector<int> G
;
    vector<Edge> edges;
    int s, t, n, m, p
;
    bool vis
;

    void init(int n, int m) {
        this->n = n; this->m = m;
        for (int i = 0; i <= n; i++)
            G[i].clear();
        edges.clear();
    }

    void AddEdge(int from, int to, int cap) {
        edges.push_back(Edge(from, to, cap, 0));
        edges.push_back(Edge(to, from, 0, 0));
        int m = edges.size();
        G[from].push_back(m - 2);
        G[to].push_back(m - 1);
    }

    bool BFS() {
        queue<int> q;
        memset(vis, 0, sizeof(vis));
        vis[s] = 1;
        q.push(s);

        while (!q.empty()) {
            int u = q.front();
            q.pop();

            for (int i = 0; i < G[u].size(); i++) {
                Edge &e = edges[G[u][i]];
                if (!vis[e.to] && e.cap > e.flow) {
                    vis[e.to] = true;
                    p[e.to] = G[u][i];
                    if (e.to == t)
                        return true;
                    q.push(e.to);
                }
            }
        }
        return false;
    }

    int Augment() {
        int flow = INF, u = t;
        while (u != s) {
            Edge &e = edges[p[u]];
            flow = min(flow, e.cap - e.flow);
            u = e.from;
        }

        u = t;
        while (u != s) {
            edges[p[u]].flow += flow;
            edges[p[u] ^ 1].flow -= flow;
            u = edges[p[u]].from;
        }
        return flow;
    }

    int Maxflow(int s, int t) {
        this->s = s; this->t = t;
        int flow = 0;

        while (BFS()) {
            flow += Augment();
        }
        return flow;
    }
};

EK ek;

int main() {
    return 0;
}


第二种:改进的模版

[code]#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXNODE = 210;
const int MAXEDGE = 100010;
typedef int Type;
const Type INF = 0x3f3f3f3f;

struct Edge{
    int u, v, next;
    Type cap, flow;
    Edge() {}
    Edge(int u, int v, Type cap, Type flow, int next): u(u), v(v), cap(cap), flow(flow), next(next){}
};

struct EK{
    int n, m, s, t;
    Edge edges[MAXEDGE];
    int head[MAXNODE], pre[MAXNODE];
    bool vis[MAXNODE];
    vector<int> cut;

    void init(int n) {
        this->n = n;
        memset(head, -1, sizeof(head));
        m = 0;
    }

    void AddEdge(int u, int v, Type cap) {
        edges[m] = Edge(u, v, cap, 0, head[u]);
        head[u] = m++;
        edges[m] = Edge(v, u, 0, 0, head[v]);
        head[v] = m++;
    }

    bool BFS() {
        queue<int> Q;
        memset(vis, 0, sizeof(vis));
        vis[s] = 1;
        Q.push(s);

        while (!Q.empty()) {
            int u = Q.front(); Q.pop();

            for (int i = head[u]; ~i; i = edges[i].next) {
                Edge &e = edges[i];
                if (!vis[e.v] && e.cap > e.flow) {
                    vis[e.v] = true;
                    pre[e.v] = i;
                    if (e.v == t)
                        return true;
                    Q.push(e.v);
                }
            }
        }
        return false;
    }

    Type Augment() {
        int u = t;
        Type flow = INF;
        while (u != s) {
            Edge &e = edges[pre[u]];
            flow = min(flow, e.cap - e.flow);
            u = e.u;
        }

        u = t;
        while (u != s) {
            edges[pre[u]].flow += flow;
            edges[pre[u] ^ 1].flow -= flow;
            u = edges[pre[u]].u;
        }
        return flow;
    }

    Type Maxflow(int s, int t) {
        this->s = s; this->t = t;
        Type flow = 0;

        while (BFS()) flow += Augment();
        return flow;
    }

    void Mincut() {
        cut.clear();
        for (int i = 0; i < m; i += 2) 
            if (vis[edges[i].u] && !vis[edges[i].v] && edges[i].cap) 
                cut.push_back(i);

    }
}ek;

int main() {
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: