P3376 【模板】网络最大流

link

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <cstring>
#include <queue>
# define LL long long
using namespace std;

const int INF=0x7fffffff;
const int maxn=10000+10;
const int maxm=100000+10;
int N,M,S,T;
int res;
int head[maxn];
int en;
struct Edge{
    int to;
    int next;
    int c;
}e[maxm<<1];

int visited[maxn];
int preedge[maxn];
int minflow[maxn];

void addEdge(int from, int to, int capa){
    e[en].next=head[from];
    e[en].to=to;
    e[en].c=capa;
    head[from]=en;
    ++en;
}

void add(int from, int to, int capa){
    addEdge(from,to,capa);
    addEdge(to,from,0);
}

void bfs(){
    memset(visited,0,sizeof(visited));
    memset(preedge,-1,sizeof(preedge));
    memset(minflow,0,sizeof(minflow));
    memset(preedge,-1,sizeof(preedge));
    minflow[S]=INF;
    visited[S]=1;
    queue<int> q;
    q.push(S);
    while(!q.empty()){
        int cur=q.front();
        q.pop();
        for(int i=head[cur];i!=-1;i=e[i].next){
            int v=e[i].to;
            if(visited[v]==1 || e[i].c<=0) continue;
            visited[v]=1;
            preedge[v]=i;
            q.push(v);
            minflow[v]=min(minflow[cur],e[i].c);
        }
    }
}

void EK(){
    while(true){
        bfs();
        if(preedge[T]==-1) break;
        res+=minflow[T];
        int v=T;
        while(true){
            int edge=preedge[v];
            int u=e[edge^1].to;
            e[edge].c-=minflow[T];
            e[edge^1].c+=minflow[T];
            if(u==S) break;
            v=u;
        }
    }
}

int main(){
    memset(head,-1,sizeof(head));
    scanf("%d %d %d %d", &N, &M, &S, &T);
    while(M--){
        int u,v;
        int c;
        scanf("%d %d %d", &u, &v, &c);
        add(u,v,c);
    }
    EK();
    printf("%d", res);
    return 0;
}

用Dinic和long long获得满分:

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <cstring>
#include <queue>
# define LL long long
using namespace std;

const LL INF = 2000000000000000;
const int maxn = 10000 + 10;
const int maxm = 100000 + 10;
int N, M, S, T;
int res;
int head[maxn];
int curh[maxn];
int en;
struct Edge {
    int to;
    int next;
    LL c;
}e[maxm << 1];

int level[maxn];
int visited[maxn];
int preedge[maxn];
int minflow[maxn];

void addEdge(int from, int to, LL capa) {
    e[en].next = head[from];
    e[en].to = to;
    e[en].c = capa;
    head[from] = en;
    ++en;
}

void add(int from, int to, LL capa) {
    addEdge(from, to, capa);
    addEdge(to, from, 0);
}

void bfs() {
    memset(level, -1, sizeof(level));
    queue<int> q;
    q.push(S);
    level[S] = 0;
    while (!q.empty()) {
        int cur = q.front();
        q.pop();
        for (int i = head[cur]; i != -1; i = e[i].next) {
            int v = e[i].to;
            if (level[v]!=-1 || e[i].c <= 0) continue;
            level[v] = level[cur] + 1;
            q.push(v);
        }
    }
}

LL dfs(int u, LL minflow) {
    if (u == T) return minflow;

    for (int i = curh[u]; i != -1; i = e[i].next) {
        curh[u] = i;
        int v=e[i].to;
        if (level[u] + 1 != level[v] || e[i].c <= 0) continue;
        LL f = dfs(v, min(minflow, e[i].c));
        if (f == 0) continue;
        e[i].c -= f;
        e[i ^ 1].c += f;
        return f;
    }
    return 0;
}

LL dinic() {
    LL res = 0;
    while (true) {
        bfs();
        if (level[T] == -1) break;
        for (int i = 1; i <= N; i++) curh[i] = head[i];
        while (true) {
            LL f = dfs(S, INF);
            if (f == 0) break;
            res += f;
        }
    }
    return res;
}

int main() {
    memset(head, -1, sizeof(head));
    scanf("%d %d %d %d", &N, &M, &S, &T);
    while (M--) {
        int u, v;
        LL c;
        scanf("%d %d %lld", &u, &v, &c);
        add(u, v, c);
    }
    LL res=dinic();
    printf("%lld", res);
    return 0;
}
原文地址:https://www.cnblogs.com/FEIIEF/p/12771423.html