min_cost_flow

#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>

using namespace std;


struct edge {
    int to;     //要到的点
    int cap;    //容量
    int cost;   //单位费用
    int rev;    //反向边
};

int V;                          //顶点数
vector<edge> G[MAXV];           //图的邻接表
int dis[MAXV];                  //最短距离
int prevv[MAXV], preve[MAXV];   //最短路中的前驱节点和对应的边

//添加边
void add_edge(int from, int to, int cap, int cost) {
    G[from].push_back((edge){to, cap, cost, G[to].size()});         //正向边
    G[to].push_back((edge){from, 0, -cost, G[from].size() - 1});    //反向边
}


//求s到t流量为f的最小费用流
//如果不能再增广则返回-1
int min_cost_flow(int s, int t, int f) {
    int res = 0;
    while(f > 0) {
        //利用Bellman-Ford算法求s到t的最短路
        fill(dis, dis + V, INF);
        dis[s] = 0;
        bool update = true;
        while(update) {
            update = false;
            for(int v = 0; v < V; ++v) {
                if(dis[v] == INF)
                    continue;
                for(int i = 0; i < G[v].size(); ++i) {
                    edge& e = G[v][i];
                    if(e.cap > 0 && dis[e.to] > dis[v] + e.cost) {
                        dis[e.to] = dis[v] + e.cost;
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        update = true;
                    }
                }
            }
        }
        if(dis[t] == INF)   //不能再增广了
            return -1;

        //沿s到t的最短路尽量增广
        int d = f;
        for(int v = t; v != s; v = prevv[v])
            d = min(d, G[prevv[v]][preve[v]].cap);
        f -= d;
        res += d * dis[t];
        for(int v = t; v != s; v = prevv[v]) {
            edge& e = G[prevv[v]][preve[v]];
            e.cap -= d;
            //cost += d * e.cost;???????????????
            G[v][e.rev].cap += d;
        }
    }
    return res;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个函数是用来求解最小费用最大流问题的。下面是代码和参数说明: ```python def min_cost_max_flow(c, u, s, t): """ 求解最小费用最大流问题 :param c: 二维数组,表示各个边的费用,c[i][j]表示从节点i到节点j的费用,如果没有边,则为float('inf') :param u: 二维数组,表示各个边的容量,u[i][j]表示从节点i到节点j的最大容量,如果没有边,则为0 :param s: 源节点 :param t: 汇节点 :return: (max_flow, min_cost),其中max_flow表示最大流量,min_cost表示最小费用 """ n = len(c) flow = 0 cost = 0 while True: # 使用Bellman-Ford算法求解最短路 dist = [float('inf')] * n dist[s] = 0 prev = [-1] * n q = [s] inqueue = [False] * n inqueue[s] = True while len(q) > 0: u = q.pop(0) inqueue[u] = False for v in range(n): if u == v or u == -1 or v == -1: continue if u != s and prev[u] != v: continue if u == s and v == t: continue if u == s and c[u][v] == float('inf'): continue if u != s and u != t and v != t and prev[u] != v: continue if u != s and u != t and v == t and prev[u] != v: continue if u == s and u != t and v != t and c[u][v] <= 0: continue if u != s and u != t and v != t and (c[u][v] <= 0 or prev[u] == v): continue new_dist = dist[u] + c[u][v] if new_dist < dist[v]: dist[v] = new_dist prev[v] = u if not inqueue[v]: q.append(v) inqueue[v] = True if prev[t] == -1: break # 计算最大流量 f = float('inf') v = t while v != s: u = prev[v] f = min(f, u[v]) v = u flow += f # 计算最小费用 v = t while v != s: u = prev[v] cost += f * c[u][v] u[v] -= f v = u return flow, cost ``` 其中,参数c和u分别表示费用和容量的二维数组,s和t分别表示源节点和汇节点。函数返回两个值,第一个值是最大流量,第二个值是最小费用。 Bellman-Ford算法是用来求解最短路径的算法,这里用来求解费用的最短路径。在这个函数中,我们使用Bellman-Ford算法来求解从源节点到汇节点的最短路径,然后根据这个最短路径来更新流量和费用。循环直到没有增广路为止,此时就得到了最小费用最大流。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值