• 最大流sap


    带当前弧优化 gap优化的sap 甚至省去了开始的bfs分层 

    虽然花了一些时间了解原理 但是感觉不亏 现在能完全独立靠原理写出具体实现了

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn = 1007, maxm = 10007, inf = 0x3f3f3f3f;
    int st, ed, tot, n, m;
    struct Edge{
        int u, v, nxt, w, f;
        Edge(){}
        Edge(int u, int v, int nxt, int w, int f):u(u), v(v), nxt(nxt), w(w), f(f){}
    }edge[maxm];
    int head[maxn], cur[maxn], gap[maxn], dep[maxn], pre[maxn];
    void init(){
        tot = 0;
        memset(head, -1, sizeof head);
    }
    void addedge(int u, int v, int w){
        edge[tot] = Edge(u, v, head[u], w, 0);
        head[u] = tot++;
        edge[tot] = Edge(v, u, head[v], 0, 0);
        head[v] = tot++;
    }
    int sap(){
        memset(gap, 0, sizeof (gap));
        memset(dep, 0, sizeof (dep));
        memcpy(cur, head, sizeof (head));
        int u = st;
        pre[u] = -1;
        gap[0] = n;
        int ans = 0;
        while(dep[st] < n){
            if(u == ed){
                int MIN = inf;
                for(int i = pre[u]; i != -1; i = pre[edge[i].u]){
                    if(MIN > edge[i].w - edge[i].f)
                        MIN = edge[i].w - edge[i].f;
                }
                for(int i = pre[u]; i != -1; i = pre[edge[i].u]){
                    edge[i].f += MIN;
                    edge[i^1].f -= MIN;
                }
                u = st;
                ans += MIN;
                continue;
            }
            bool flag = false;
            int v;
            for(int i = cur[u]; i != -1; i = edge[i].nxt){
                v = edge[i].v;
                if(edge[i].w - edge[i].f && dep[v]+1 == dep[u]){
                    flag = true;
                    cur[u] = pre[v] = i;
                    break;
                }
            }
            if(flag){
                u = v;
                continue;
            }
            int MIN = n;
            for(int i = head[u]; i != -1; i = edge[i].nxt){
                if(edge[i].w - edge[i].f && dep[edge[i].v] < MIN){
                    MIN = dep[edge[i].v];
                    cur[u] = i;
                }
            }
            gap[dep[u]]--;
            if(!gap[dep[u]])
                return ans;
            dep[u] = MIN+1;
            gap[dep[u]]++;
            if(u != st)
                u = edge[pre[u]].u;
        }
        return ans;
    }
    int main(){
        int t, kase = 1;
        scanf("%d", &t);
        while(t--){
            init();
            scanf("%d%d", &n, &m);
            while(m--){
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                addedge(u, v, w);
            }
            st = 1, ed = n;
            printf("Case %d: ", kase++);
            printf("%d
    ", sap());
        }
        return 0;
    }
    搞图论是没有用的,转行做数学题了hh
  • 相关阅读:
    2019.1.5JavaScript
    SQL常用删改增语句
    PHP连接数据库
    PHP数组函数
    PHP字符串常用函数
    PHP 类型判断方法
    jQuery效果
    jQuery特性
    倒计时
    判断浏览器及其内核
  • 原文地址:https://www.cnblogs.com/DearDongchen/p/7594543.html
Copyright © 2020-2023  润新知