最小费用最大流模板

最小费用最大流一般用邻接表来实现,因为邻接矩阵不能处理平行边等等;而一条有向边是要储存两条信息,无向图的话要拆成两条有向边处理,相当于变为4条边,这也是邻接矩阵不能做到的

然后最小费用最大流的原理就不讲了,讲一下实现的要注意的问题和一些技巧

1.用结构体数组来保存边,最好从下标0开始保存不要从下标1开始保存,因为增广的时候需要用到位运算,从下标1保存不利于位运算

2.记录路径:如果是邻接矩阵记录前驱p[v]=u,表示一条边u—>v,u就是v的前驱

所以找出整条路径就是一个循环 for(u=t; u!=s; u=p[u])

邻接表p[v]=i; //i表示的是第i条边,那么它的前驱应该是e[i].u,即在这条边的信息内部

所以找出整条路径是 for(i=p[t]; i!=-1; i=p[e[i].u]) //i表示的是边的标号

3.最小费用最大流:

I.在还能增流的条件下,以单位费用作为权去求源点到汇点最短路并且需要记录路径,但记住不要改变流量,改变流量是增广的时候做的,因为单位费用可能有负值所以用spfa。(spfa算法)

II.如果能得到到汇点的最短路,说明还没到达最小费用最大流,那么就沿刚才记录的路径返回,找出最小残余流量

III.增广:即再沿路径返回一次,添加残余流量,反向则减少残余流量

IV.更新最大流,和最小费用 即F+=min; C+=d[t]*min; //min是本次的最小参与流量

#define MAXN 1003
#define MAXM 40004
using namespace std; 
const int INF = 0x3f3f3f3f;
struct EDGE{
    int to, cap, next, flow, cost;
}edge[MAXM];
int q[MAXN], head[MAXN], tol;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int n, m;
void init(){
    tol = 0;
    memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int cap, int cost){
    edge[tol].cap = cap;
    edge[tol].cost = cost;
    edge[tol].flow = 0;
    edge[tol].next = head[u];
    edge[tol].to = v;
    head[u] = tol++;
    edge[tol].cap = 0;
    edge[tol].cost
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值