【最大流模板——Dinic算法】【有向图】

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int inf = 0x3f3f3f3f;
const int N = 214;
const int M = 214;

struct Edge{
    int v;
    int cap;/*边的容量*/
    int next;
}edge[M<<1];

int cnt, head[N], level[N];

void Init();
void add_edge(int u, int v, int w);
bool bfs(int s, int t);
int dfs(int u, int t, int f);
int max_flow(int s, int t);

int main(){
    int n, m, i, u, v, w;
    while(~scanf("%d %d", &n, &m)){
        Init();
        for(i = 0; i < n; i++){
            scanf("%d %d %d", &u, &v, &w);
            add_edge(u, v, w);
        }
        printf("%d\n", max_flow(1, m));
    }
    return 0;
}
void Init(){
    cnt = 0;/*必须初始化为零-异或运算改变反向弧*/
    memset(head, -1, sizeof(head));
}
void add_edge(int u, int v, int w){
    edge[cnt].v = v;
    edge[cnt].cap = w;
    edge[cnt].next = head[u];
    head[u] = cnt++;

    edge[cnt].v = u;
    edge[cnt].cap = 0;/*有向图反向弧容量初始化为0*/
    edge[cnt].next = head[v];
    head[v] = cnt++;
}
bool bfs(int s, int t){/*bfs构造分层网络*/
    queue <int> q;
    memset(level, -1, sizeof(level));
    level[s] = 0;
    q.push(s);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        for(int i = head[u]; ~i; i = edge[i].next){
            int v = edge[i].v;
            if(edge[i].cap > 0 && level[v] == -1){
                level[v] = level[u] + 1;
                q.push(v);
            }
        }
    }
    if(level[t] != -1)
        return true;
    else
        return false;
}
int dfs(int u, int t, int f){/*dfs沿阻塞流增广*/
    if(u == t)
        return f;
    int flow = 0, d;
    for(int i = head[u]; ~i; i = edge[i].next){
        int v = edge[i].v;
        if(edge[i].cap > 0 && level[u] < level[v] && (d = dfs(v, t, min(edge[i].cap, f)))){
            edge[i].cap -= d;
            edge[i^1].cap += d;
            flow += d;
            f -= d;
            if(!f)
                break;
        }
    }
    if(flow == 0)
        level[u] = -1;
    return flow;
}
int max_flow(int s, int t){
    int flow = 0;
    while(bfs(s, t)){
        flow += dfs(s, t, inf);
    }
    return flow;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值