最大流

最大流也就是最小割。

dinic

每次BFS出一条合法的路径来,然后DFS增广这条路径,直到再无可增广的路径

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
 
using namespace std;
const int N=2e5+7,inf=2e9+7;
int read()
{
    int a = 0,x = 1;
    char ch = getchar();
    while(ch > '9' || ch < '0'){
        if(ch == '-') x = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){ 
        a = a*10 + ch-'0';
        ch = getchar();
    }
    return a*x;
}
 
int n,m;
int head[N],go[N],nxt[N],cnt=-1,val[N];
void add(int u,int v,int w)
{
    go[++cnt] = v;
    nxt[cnt] = head[u];
    head[u] = cnt;
    val[cnt] = w;
}
 
int dis[N];
bool BFS(int pos)
{
    queue<int>q;
    q.push(pos);
    memset(dis,0,sizeof(dis));
    dis[pos] = 1;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int e = head[u];~e;e = nxt[e]){
            int v = go[e];
            if(dis[v] || !val[e]) continue;
            dis[v] = dis[u] + 1;
            q.push(v);
        }
    }
    return dis[n];
}
 
int dfs(int u,int limit)
{
    if(!limit || u == n) return limit;
    int ret = 0;
    for(int e = head[u];~e;e = nxt[e]){
        int v = go[e];
        if(dis[v] != dis[u]+1) continue;
        int tmp = dfs(v,min(val[e],limit));
        limit -= tmp;
        val[e] -= tmp,val[e^1] += tmp;
        ret += tmp;
    }
    return ret;
}
 
int main()
{
    m = read(),n = read();
    memset(nxt,-1,sizeof(nxt));
    memset(head,-1,sizeof(head));
    for(int i = 1;i <= m;i ++) {
        int u = read(),v = read(),w = read();
        add(u,v,w);add(v,u,0);
    }
    int ans = 0;
    while(BFS(1)){
    //  printf("!");
        ans += dfs(1,inf);
    }
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/nao-nao/p/13693363.html