MinCostMaxFlow(SPFA)算法

算法:MinCostMaxFlow(SPFA)
问题:最小费用最大流问题
输入:带有w(容量)和c(费用)的有向图
输出:最小费用、最大流
备注:不要吝啬内存

#include<bits/stdc++.h>
#define INF 0x3fffffff
#define maxn 100
#define maxm 10000
using namespace std;

int pre[maxn],dis[maxn];
int vis[maxn],cnt[maxn];
int n,m,src,tar;

int head[maxn],tot;
struct Edge {
    int from,to;
    int w,c,nxt;
} e[maxm];

void adde(int f,int t,int w,int c){
    e[tot]=Edge{f,t,w,c,head[f]};
    head[f]=tot++;
    e[tot]=Edge{t,f,0,-c,head[t]};
    head[t]=tot++;
}

int mincost,maxflow;
int spfa() {
    for(int i=0; i<n; i++)
        dis[i]=INF;
    memset(vis,0,sizeof(vis));
    memset(cnt,0,sizeof(cnt));

    queue<int>p;
    p.push(src);
    dis[src]=0;
    vis[src]=1;
    cnt[src]=1;
    while(!p.empty()) {
        int u=p.front(); p.pop();
        vis[u]=0;
        for(int i=head[u]; ~i; i=e[i].nxt) {
            int v=e[i].to;
            if(e[i].w&&dis[v]>dis[u]+e[i].c) {
                dis[v]=dis[u]+e[i].c;
                pre[v]=i;
                if(!vis[v]) {
                    p.push(v);
                    vis[v]=1;
                    cnt[v]++;
                    if(cnt[v]>n) return 0;
                }
            }
        }
    }
    return dis[tar]<INF;
}

void MCMF() {
    maxflow=0;
    mincost=0;
    while(spfa()) {
        int f=INF;
        for(int i=tar;i!=src;i=e[pre[i]].from)
            f=min(f,e[pre[i]].w);
        assert(f>0);
        assert(dis[tar]<INF);
        for(int i=tar;i!=src;i=e[pre[i]].from) {
            e[pre[i]^1].w+=f;
            e[pre[i]].w-=f;
        }

        maxflow+=f;
        mincost+=dis[tar]*f;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。