最小费用最大流问题

下面给网络流增加了一个因素:费用

//连续最短路径算法
//消圈算法
//先求最大流, 再在Gf中寻找负费用圈并沿它增广
//KM算法
//二分图的最优匹配 短距离图优势很大
//ZKW算法
//KM+SAP(Shortest Augmenting Path最短增广路)
//原始对偶(Primal-Dual)算法

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
using namespace std;

//S 源点   T汇点 n点的个数

struct node
{
	int v;//该边连向的点
	int f;//流量
	int w;//权值
	int next;//下一条边
}edge[Maxm]  //有向边   注意一条边用两条边存

int head[n];//邻接表头数组   初始化为-1
int cnt; //建边计数器    初始化为0
int pre[n];//前驱数组  初始化为-1
int dis[n];//花费数组  类似最短路距离数组
bool vis[n];//标记数组   用于SPFA时记录是否访问过

bool spfa() //基于邻接表的SPFA算法
{
    int i;
    for(i=0; i<n; i++)  //初始化
    {
        pre[i]=-1;
        dis[i]=inf;
        vis[i]=false;
    }
    queue <int > q;
    dis[S]=0;
    vis[S]=true;
    q.push(S);
    while(!q.empty())
    {
        int t=q.front();
        q.pop();
        i=head[t];
        vis[t]=false;
        while(i!=-1)
        {
            if(edge[i].f>0&&dis[edge[i].v]>dis[t]+edge[i].w)
            {
                dis[edge[i].v]=dis[t]+edge[i].w;
                pre[edge[i].v]=i;
                if(!vis[edge[i].v])
                {
                    vis[edge[i].v]=true;
                    q.push(edge[i].v);
                }
            }
            i=edge[i].next;
        }
    }
    if(pre[T]==-1)//如果不在最短路中   代表着最短路寻找失败
    {
        return false;
    }
    return true;
}
int MinCostMaxFlow()
{
    int ans=0;
    while(spfa())  //如果最短增广路寻找成功
    {
        int max1=inf;
        int p=pre[T];//初始化P指针
        while(p!=-1) //寻找关键流量
        {
            max1=min(max1,edge[p].f);
            p=pre[edge[p].u];
        }
        p=pre[T];
        while(p!=-1)  //修改流量
        {
            edge[p].f-=max1;
            edge[p^1].f+=max1;
            ans+=max1*edge[p].w;
            p=pre[edge[p].u];
        }
    }
    return ans;
}




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值