• 网络流算法


    SAP算法:最大流

    // ALGORITHM_MAXFLOW_SAP ->
    
    #ifdef ALGORITHM_MAXFLOW_SAP_ENABLED
    
    #define ALGORITHM_MAXFLOW_SAP_MAXN 20010
    #define ALGORITHM_MAXFLOW_SAP_MAXM 880010
    #define ALGORITHM_MAXFLOW_SAP_INF 0x7FFFFFFF
    
    struct ALGORITHM_MAXFLOW_SAP_Node {
        int from, to, next;
        int cap;
    } ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_MAXM];
    int ALGORITHM_MAXFLOW_SAP_tol;
    int ALGORITHM_MAXFLOW_SAP_head[ALGORITHM_MAXFLOW_SAP_MAXN];
    int ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_MAXN];
    int ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_MAXN];
    int ALGORITHM_MAXFLOW_SAP_cur[ALGORITHM_MAXFLOW_SAP_MAXN];
    int ALGORITHM_MAXFLOW_SAP_S[ALGORITHM_MAXFLOW_SAP_MAXN];
    int ALGORITHM_MAXFLOW_SAP_que[ALGORITHM_MAXFLOW_SAP_MAXN];
    int ALGORITHM_MAXFLOW_SAP_n;
    
    void ALGORITHM_MAXFLOW_SAP_clear() {
        ALGORITHM_MAXFLOW_SAP_tol = 0;
        memset(ALGORITHM_MAXFLOW_SAP_head, -1, sizeof(ALGORITHM_MAXFLOW_SAP_head));
    }
    
    void ALGORITHM_MAXFLOW_SAP_addedge(int u, int v, int w) {
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].from = u;
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].to = v;
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].cap = w;
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].next = ALGORITHM_MAXFLOW_SAP_head[u];
        ALGORITHM_MAXFLOW_SAP_head[u] = ALGORITHM_MAXFLOW_SAP_tol++;
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].from = v;
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].to = u;
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].cap = 0;
        ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].next = ALGORITHM_MAXFLOW_SAP_head[v];
        ALGORITHM_MAXFLOW_SAP_head[v] = ALGORITHM_MAXFLOW_SAP_tol++;
    }
    void ALGORITHM_MAXFLOW_SAP_BFS(int start, int end) {
        memset(ALGORITHM_MAXFLOW_SAP_dep, -1, sizeof(ALGORITHM_MAXFLOW_SAP_dep));
        memset(ALGORITHM_MAXFLOW_SAP_gap, 0, sizeof(ALGORITHM_MAXFLOW_SAP_gap));
        ALGORITHM_MAXFLOW_SAP_gap[0] = 1;
        int front, rear;
        front = rear = 0;
        ALGORITHM_MAXFLOW_SAP_dep[end] = 0;
        ALGORITHM_MAXFLOW_SAP_que[rear++] = end;
        while (front != rear) {
            int u = ALGORITHM_MAXFLOW_SAP_que[front++];
            if (front == ALGORITHM_MAXFLOW_SAP_MAXN) {
                front = 0;
            }
            for (int i = ALGORITHM_MAXFLOW_SAP_head[u]; i != -1; i = ALGORITHM_MAXFLOW_SAP_edge[i].next) {
                int v = ALGORITHM_MAXFLOW_SAP_edge[i].to;
                if (ALGORITHM_MAXFLOW_SAP_dep[v] != -1) {
                    continue;
                }
                ALGORITHM_MAXFLOW_SAP_que[rear++] = v;
                if (rear == ALGORITHM_MAXFLOW_SAP_MAXN) {
                    rear = 0;
                }
                ALGORITHM_MAXFLOW_SAP_dep[v] = ALGORITHM_MAXFLOW_SAP_dep[u] + 1;
                ++ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[v]];
            }
        }
    }
    int ALGORITHM_MAXFLOW_SAP_SAP(int start, int end) {
        int res = 0;
        ALGORITHM_MAXFLOW_SAP_BFS(start, end);
        int top = 0;
        memcpy(ALGORITHM_MAXFLOW_SAP_cur, ALGORITHM_MAXFLOW_SAP_head, sizeof(ALGORITHM_MAXFLOW_SAP_head));
        int u = start;
        int i;
        while (ALGORITHM_MAXFLOW_SAP_dep[start] < ALGORITHM_MAXFLOW_SAP_n) {
            if (u == end) {
                int temp = ALGORITHM_MAXFLOW_SAP_INF;
                int inser;
                for (i = 0; i < top; i++)
                    if (temp > ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i]].cap) {
                        temp = ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i]].cap;
                        inser = i;
                    }
                for (i = 0; i < top; i++) {
                    ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i]].cap -= temp;
                    ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i] ^ 1].cap += temp;
                }
                res += temp;
                top = inser;
                u = ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[top]].from;
            }
            if (u != end && ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[u] - 1] == 0) {
                break;
            }
            for (i = ALGORITHM_MAXFLOW_SAP_cur[u]; i != -1; i = ALGORITHM_MAXFLOW_SAP_edge[i].next)
                if (ALGORITHM_MAXFLOW_SAP_edge[i].cap != 0 && ALGORITHM_MAXFLOW_SAP_dep[u] == ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_edge[i].to] + 1) {
                    break;
                }
            if (i != -1) {
                ALGORITHM_MAXFLOW_SAP_cur[u] = i;
                ALGORITHM_MAXFLOW_SAP_S[top++] = i;
                u = ALGORITHM_MAXFLOW_SAP_edge[i].to;
            } else {
                int min = ALGORITHM_MAXFLOW_SAP_n;
                for (i = ALGORITHM_MAXFLOW_SAP_head[u]; i != -1; i = ALGORITHM_MAXFLOW_SAP_edge[i].next) {
                    if (ALGORITHM_MAXFLOW_SAP_edge[i].cap == 0) {
                        continue;
                    }
                    if (min > ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_edge[i].to]) {
                        min = ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_edge[i].to];
                        ALGORITHM_MAXFLOW_SAP_cur[u] = i;
                    }
                }
                --ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[u]];
                ALGORITHM_MAXFLOW_SAP_dep[u] = min + 1;
                ++ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[u]];
                if (u != start) {
                    u = ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[--top]].from;
                }
            }
        }
        return res;
    }
    
    #endif
    
    // <- ALGORITHM_MAXFLOW_SAP
    View Code

    #define ALGORITHM_MAXFLOW_SAP_ENABLED 允许SAP算法进行编译

    ALGORITHM_MAXFLOW_SAP_MAXN 点的最大数目

    ALGORITHM_MAXFLOW_SAP_MAXM 边的最大数目
    ALGORITHM_MAXFLOW_SAP_n 点的数目

    ALGORITHM_MAXFLOW_SAP_clear() 清空数据结构
    ALGORITHM_MAXFLOW_SAP_addedge(u,v,w) 添加一条从u到v容量为w的弧
    ALGORITHM_MAXFLOW_SAP_SAP(s,t) 从s到t的最大流

    类实现:

    class MaxFlow_SAP {
    public:
    #define SAP_MAXN 20010
    #define SAP_MAXM 880010
    #define SAP_INF 0x3FFFFFFF
    
        struct Node {
            int from, to, next;
            int cap;
        } edge[SAP_MAXM];
        int tol;
        int head[SAP_MAXN];
        int dep[SAP_MAXN];
        int gap[SAP_MAXN];
        int cur[SAP_MAXN];
        int S[SAP_MAXN];
        int que[SAP_MAXN];
        int n;
        MaxFlow_SAP() {
            clear();
        }
        void clear() {
            tol = 0;
            memset(head, -1, sizeof(head));
        }
    
        void addedge(int u, int v, int w) {
            edge[tol].from = u;
            edge[tol].to = v;
            edge[tol].cap = w;
            edge[tol].next = head[u];
            head[u] = tol++;
            edge[tol].from = v;
            edge[tol].to = u;
            edge[tol].cap = 0;
            edge[tol].next = head[v];
            head[v] = tol++;
        }
        void BFS(int start, int end) {
            memset(dep, -1, sizeof(dep));
            memset(gap, 0, sizeof(gap));
            gap[0] = 1;
            int front, rear;
            front = rear = 0;
            dep[end] = 0;
            que[rear++] = end;
            while (front != rear) {
                int u = que[front++];
                if (front == SAP_MAXN) {
                    front = 0;
                }
                for (int i = head[u]; i != -1; i = edge[i].next) {
                    int v = edge[i].to;
                    if (dep[v] != -1) {
                        continue;
                    }
                    que[rear++] = v;
                    if (rear == SAP_MAXN) {
                        rear = 0;
                    }
                    dep[v] = dep[u] + 1;
                    ++gap[dep[v]];
                }
            }
        }
        int SAP(int start, int end) {
            int res = 0;
            BFS(start, end);
            int top = 0;
            memcpy(cur, head, sizeof(head));
            int u = start;
            int i;
            while (dep[start] < n) {
                if (u == end) {
                    int temp = SAP_INF;
                    int inser;
                    for (i = 0; i < top; i++)
                        if (temp > edge[S[i]].cap) {
                            temp = edge[S[i]].cap;
                            inser = i;
                        }
                    for (i = 0; i < top; i++) {
                        edge[S[i]].cap -= temp;
                        edge[S[i] ^ 1].cap += temp;
                    }
                    res += temp;
                    top = inser;
                    u = edge[S[top]].from;
                }
                if (u != end && gap[dep[u] - 1] == 0) {
                    break;
                }
                for (i = cur[u]; i != -1; i = edge[i].next)
                    if (edge[i].cap != 0 && dep[u] == dep[edge[i].to] + 1) {
                        break;
                    }
                if (i != -1) {
                    cur[u] = i;
                    S[top++] = i;
                    u = edge[i].to;
                } else {
                    int min = n;
                    for (i = head[u]; i != -1; i = edge[i].next) {
                        if (edge[i].cap == 0) {
                            continue;
                        }
                        if (min > dep[edge[i].to]) {
                            min = dep[edge[i].to];
                            cur[u] = i;
                        }
                    }
                    --gap[dep[u]];
                    dep[u] = min + 1;
                    ++gap[dep[u]];
                    if (u != start) {
                        u = edge[S[--top]].from;
                    }
                }
            }
            return res;
        }
    };
    View Code

    最小费用最大流

     
    //ALGORITHM MINCOSTFLOW ->
    #define ALGORITHM_MINCOSTFLOW_MAXN 600
    #define ALGORITHM_MINCOSTFLOW_MAXM 360000
    #define ALGORITHM_MINCOSTFLOW_INF 0X7FFFFFFF
    struct ALGORITHM_MINCOSTFLOW_Edge {
        int v;
        int val;
        int cost;
        int next;
    } ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_MAXM];
    int ALGORITHM_MINCOSTFLOW_head[ALGORITHM_MINCOSTFLOW_MAXN];
    int ALGORITHM_MINCOSTFLOW_countedge;
    int ALGORITHM_MINCOSTFLOW_pre[ALGORITHM_MINCOSTFLOW_MAXN];
    int ALGORITHM_MINCOSTFLOW_pos[ALGORITHM_MINCOSTFLOW_MAXN];
    int ALGORITHM_MINCOSTFLOW_dis[ALGORITHM_MINCOSTFLOW_MAXN];
    int ALGORITHM_MINCOSTFLOW_que[ALGORITHM_MINCOSTFLOW_MAXM];
    bool ALGORITHM_MINCOSTFLOW_vis[ALGORITHM_MINCOSTFLOW_MAXN];
    void ALGORITHM_MINCOSTFLOW_addedge(int u, int v, int val, int cost) {
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].v = v;
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].val = val;
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].cost = cost;
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].next = ALGORITHM_MINCOSTFLOW_head[u];
        ALGORITHM_MINCOSTFLOW_head[u] = ALGORITHM_MINCOSTFLOW_countedge++;
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].v = u;
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].val = 0;
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].cost = -cost;
        ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].next = ALGORITHM_MINCOSTFLOW_head[v];
        ALGORITHM_MINCOSTFLOW_head[v] = ALGORITHM_MINCOSTFLOW_countedge++;
    }
    void ALGORITHM_MINCOSTFLOW_clear() {
        memset(ALGORITHM_MINCOSTFLOW_head, -1, sizeof(ALGORITHM_MINCOSTFLOW_head));
        ALGORITHM_MINCOSTFLOW_countedge = 0;
    }
    bool ALGORITHM_MINCOSTFLOW_spfa(int s, int t) {
        memset(ALGORITHM_MINCOSTFLOW_pre, -1, sizeof(ALGORITHM_MINCOSTFLOW_pre));
        memset(ALGORITHM_MINCOSTFLOW_vis, 0, sizeof(ALGORITHM_MINCOSTFLOW_vis));
        int Head, tail;
        Head = tail = 0;
        for (int i = 0; i < ALGORITHM_MINCOSTFLOW_MAXN; i++) {
            ALGORITHM_MINCOSTFLOW_dis[i] = ALGORITHM_MINCOSTFLOW_INF;
        }
        ALGORITHM_MINCOSTFLOW_que[tail++] = s;
        ALGORITHM_MINCOSTFLOW_pre[s] = s;
        ALGORITHM_MINCOSTFLOW_dis[s] = 0;
        ALGORITHM_MINCOSTFLOW_vis[s] = 1;
        while (Head != tail) {
            int now = ALGORITHM_MINCOSTFLOW_que[Head++];
            ALGORITHM_MINCOSTFLOW_vis[now] = 0;
            for (int i = ALGORITHM_MINCOSTFLOW_head[now]; i != -1; i = ALGORITHM_MINCOSTFLOW_edge[i].next) {
                int adj = ALGORITHM_MINCOSTFLOW_edge[i].v;
                if (ALGORITHM_MINCOSTFLOW_edge[i].val > 0 && ALGORITHM_MINCOSTFLOW_dis[now] + ALGORITHM_MINCOSTFLOW_edge[i].cost < ALGORITHM_MINCOSTFLOW_dis[adj]) {
                    ALGORITHM_MINCOSTFLOW_dis[adj] = ALGORITHM_MINCOSTFLOW_dis[now] + ALGORITHM_MINCOSTFLOW_edge[i].cost;
                    ALGORITHM_MINCOSTFLOW_pre[adj] = now;
                    ALGORITHM_MINCOSTFLOW_pos[adj] = i;
                    if (!ALGORITHM_MINCOSTFLOW_vis[adj]) {
                        ALGORITHM_MINCOSTFLOW_vis[adj] = 1;
                        ALGORITHM_MINCOSTFLOW_que[tail++] = adj;
                    }
                }
            }
        }
        return ALGORITHM_MINCOSTFLOW_pre[t] != -1;
    }
    int ALGORITHM_MINCOSTFLOW_MinCostFlow(int s, int t) {
        int cost = 0, flow = 0;
        while (ALGORITHM_MINCOSTFLOW_spfa(s, t)) {
            int f = ALGORITHM_MINCOSTFLOW_INF;
            for (int i = t; i != s; i = ALGORITHM_MINCOSTFLOW_pre[i])
                if (ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i]].val < f) {
                    f = ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i]].val;
                }
            flow += f;
            cost += ALGORITHM_MINCOSTFLOW_dis[t] * f;
            for (int i = t; i != s; i = ALGORITHM_MINCOSTFLOW_pre[i]) {
                ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i]].val -= f;
                ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i] ^ 1].val += f;
            }
        }
        return cost;
    }
    // <- ALGORITHM MINCOSTFLOW
    View Code

    ALGORITHM_MINCOSTFLOW_MAXN 点的最大数目
    ALGORITHM_MINCOSTFLOW_MAXM 边的最大数目
    ALGORITHM_MINCOSTFLOW_clear() 清空数据结构
    ALGORITHM_MINCOSTFLOW_addedge(u,v,val,cost) 增加从u到v,容量为val,费用为cost的弧
    ALGORITHM_MINCOSTFLOW_MinCostFlow(s,t) 从s到t的最小费用最大流

  • 相关阅读:
    数组中寻找和为X的两个元素
    JSP&Servlet学习笔记(一)
    自下而上的动态规划算法
    计数排序
    快速排序
    堆排序
    LeetCode-001题解
    算法不归路之最大子序列(C++版)
    算法不归路之插入排序(C版)
    互联网五层模型
  • 原文地址:https://www.cnblogs.com/dramstadt/p/5964975.html
Copyright © 2020-2023  润新知