前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单易懂的Dinic算法C++实现 含算法解释

简单易懂的Dinic算法C++实现 含算法解释

作者头像
丹牛Daniel
发布2022-11-18 10:05:21
4930
发布2022-11-18 10:05:21
举报

目录

程序思想

提示

C++代码

程序实现截图 


学习了Dinic算法,尝试通过算法思想使用C++实现了一下。

程序思想

  1. 1)初始化程序,设置容量网络和网络流
  2. 2)DFS()构造残留网络、BFS()构造层次网络,层次网络中找不到汇点便结束算法
  3. 3)在层次网络中不断进行增广,知道层次网络中没有增广路;每次增广都要去掉已饱和的弧
  4. 4)转到步骤2)

提示

程序中Dinic()循坏调用BFS()不断构建层次网络,每次构建好调用则循环DFS()增广,因此步骤2,3的一次循环便是一个阶段,每个阶段中都是根据残留网络建立层次网络然后进行增广,直到找不到增广路为止。在程序实现的时候,并不需要真正“构造”层次网络,只需要对每个顶点标记层次,增广的时候,判断边是否满足layer(v) = layer(u)+1这一约束条件即可。

C++代码

代码语言:javascript
复制
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

//邻接矩阵存储图 储存容量和流量 
struct Vertex
{
    int c;
    int f;
}G[100][100];

int Edge, Vex; // 边数 节点数 
int layer[100]; //层数数组 
int v_s, v_e, v_c; // 每条边起点、终点和流量 
const int INF = 0x7fffffff;

bool BFS(); // 广度优先BFS构造层次网络 
int DFS(int u, int cp); // 深度优先DFS找寻增广路
int Dinic(); // Dinic算法 

int Dinic() {
    int sum=0, tf=0;
    while (BFS()) {
        while (tf = DFS(1, INF))
            sum += tf;
    }
    return sum;
}

bool BFS()     
{
    queue<int> q;
    memset(layer, 0, sizeof(layer));
    q.push(1);
    layer[1] = 1;
    int u, v;
    while (!q.empty()) {
        u = q.front();
        q.pop();
        for (v = 1; v <= Vex; v++) {
            if (!layer[v] && G[u][v].c>G[u][v].f) {
                layer[v] = layer[u] + 1;
                q.push(v);
            }
        }
    }
    return layer[Vex] != 0;              
}

int DFS(int u, int cp) {         
    int tmp = cp;
    int v, t;
    if (u == Vex)
        return cp;
    for (v = 1; v <= Vex&&tmp; v++) {
        if (layer[u] + 1 == layer[v]) {
            if (G[u][v].c>G[u][v].f) {
                t = DFS(v, min(tmp, G[u][v].c - G[u][v].f));
                G[u][v].f += t;
                G[v][u].f -= t;
                tmp -= t;
            }
        }
    }
    return cp - tmp;
}


int main() {
	printf("请输入边数和节点数(空格隔开):\n"); 
    while (scanf("%d%d", &Edge, &Vex)) {
        memset(G, 0, sizeof(G));
        if(Edge!=0) printf("请输入每条边起点 终点 权值:\n") ;
        while (Edge--) {
            scanf("%d%d%d", &v_s, &v_e, &v_c);
            G[v_s][v_e].c += v_c;
        }
        int max_c = Dinic();
        printf("\n汇点最大流量为:%d", max_c);
    }
    return 0;
}

程序实现截图 

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 程序思想
    • 提示
    • C++代码
    • 程序实现截图 
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档