P3376 [模板] 网络最大流

https://www.luogu.org/blog/ONE-PIECE/wang-lao-liu-jiang-xie-zhi-dinic 

EK 292ms

#include <bits/stdc++.h>
using namespace std;

int n, m, s, t, cnt;
int l, r;
struct node {
    int to, nex, val;
}E[200005];
int head[100005];

int vis[10005];
int que[10005];

struct no1 {
    int to, edge;
}pre[10005];

bool bfs() {
    for(int i = 1; i <= r; i++) {
        vis[que[i]] = 0;
        pre[i].to = -1;
        pre[i].edge = -1;
    }
    l = 1, r = 0;
    vis[s] = 1;
    que[++r] = s;

    while(l <= r) {
        int u = que[l];
        l++;

        for(int i = head[u]; i; i = E[i].nex) {
            int v = E[i].to;

            if(!vis[v] && E[i].val > 0) {
                pre[v].to = u;
                pre[v].edge = i;
                if(v == t) return true;
                vis[v] = 1;
                que[++r] = v;
            }
        }
    }
    return false;
}

int EK() {
    int res = 0;
    while(bfs()) {
        int mi = 1e9;
        for(int i = t; i != s; i = pre[i].to) {
            mi = min(mi, E[pre[i].edge].val);
        }

        for(int i = t; i != s; i = pre[i].to) {
            E[pre[i].edge].val -= mi;
            E[pre[i].edge ^ 1].val += mi;
        }
        res += mi;
    }
    return res;
}


int main() {
    scanf("%d%d%d%d", &n, &m, &s, &t);
    cnt = 1;

    for(int i = 1; i <= m; i++) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        E[++cnt].to = b; E[cnt].nex = head[a]; E[cnt].val = c; head[a] = cnt;
        E[++cnt].to = a; E[cnt].nex = head[b]; E[cnt].val = 0; head[b] = cnt;
    }
    printf("%d\n", EK());
    return 0;
}
View Code

 

Dinic多路增广 + 弧优化 199ms

#include <bits/stdc++.h>
using namespace std;

int n, m, s, t, cnt;
int maxflow;
struct node {
    int to, nex, val;
}E[200005];
int head[10005];
int cur[10005];

int dep[10005];
int inque[10005];
bool bfs() {
    for(int i = 1; i <= n; i++) cur[i] = head[i], dep[i] = 0x3f3f3f3f, inque[i] = 0;
    dep[s] = 0;
    queue<int> que;
    que.push(s);
    inque[s] = 1;

    while(!que.empty()) {
        int u = que.front();
        que.pop();
        inque[u] = 0;

        for(int i = head[u]; i; i = E[i].nex) {
            int v = E[i].to;
            if(E[i].val > 0 && dep[v] > dep[u] + 1) {
                dep[v] = dep[u] + 1;
                if(!inque[v]) {
                    inque[v] = 1;
                    que.push(v);
                }
            }
        }
    }
    if(dep[t] != 0x3f3f3f3f) return true;
    else return false;
}

int vis;
int dfs(int x, int flow) {
    int rlow = 0;
    if(x == t) {
        vis = 1;
        maxflow += flow;
        return flow;
    }
    int used = 0; //当前使用了多少
    for(int i = cur[x]; i; i = E[i].nex) {
        cur[x] = i;  //更新弧
        int v = E[i].to;
        if(E[i].val > 0 && dep[v] == dep[x] + 1) {
            if(rlow = dfs(v, min(flow - used, E[i].val))) {
                used += rlow;
                E[i].val -= rlow;
                E[i ^ 1].val += rlow;
                if(used == flow) break; //用完了
            }
        }
    }
    return used;
}

void dinic() {
    int lowflow;
    while(bfs()) {
        vis = 1;
        while(vis) {
            vis = 0;
            dfs(s, 1000000000);
        }
    }
}

int main() {
    scanf("%d%d%d%d", &n, &m, &s, &t);
    cnt = 1;
    maxflow = 0;

    for(int i = 1; i <= m; i++) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        E[++cnt].to = b; E[cnt].nex = head[a]; E[cnt].val = c; head[a] = cnt;
        E[++cnt].to = a; E[cnt].nex = head[b]; E[cnt].val = 0; head[b] = cnt;
    }
    dinic();
    printf("%d\n", maxflow);
    return 0;
}
View Code

 

posted @ 2019-07-06 07:22  lwqq3  阅读(191)  评论(0编辑  收藏  举报