最小费用最大流模板

注意,spfa可能被卡,图中存在负权

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int _ = 2e5+10;
const int N = 1010,inf=0x3f3f3f3f;

void in(int &x){
    x=0;int y = 1;
    char c=getchar();
    while(!isdigit(c)){if(c=='-')y=-1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    x*=y;
}
void o(int x){
    printf("%lld",x);
}

int n,m,k;
int a[_];


//前向星村边,注意始边从2开始,而不再是1。
struct Minicostflow{
    // 起始,终点,
    int S,T,n;
    //边,注意要存u
    struct EDG{int u,v,nxt,f,cost;}e[_];int cnt = 1;
    int head[_];
    // 反边花费为-cos
    void add(int u,int v,int f,int cos){
        e[++cnt]={u,v,head[u],f,cos};head[u]=cnt;
        swap(u,v);
        e[++cnt]={u,v,head[u],0,-cos};head[u]=cnt;
    }
    //spfa 建立分层图
    int dis[_],in_queue[_],from[_];
    bool spfa(){
        for(int i=1;i<=n;i++)dis[i]=inf,in_queue[i]=0;
        queue<int>q;q.push(S);dis[S]=0;in_queue[S]=1;
        while(!q.empty()){
            int u = q.front(); q.pop();
            if(u==T)continue;
            for(int i=head[u];i;i=e[i].nxt){
                EDG P = e[i];
                if(P.f&&dis[P.v]>dis[u]+P.cost){
                    dis[P.v]=dis[u]+P.cost;
                    from[P.v]=i;
                    if(!in_queue[P.v]){
                        in_queue[P.v]=1;
                        q.push(P.v);
                    }
                }

            }
            in_queue[u]=0;
        }
        return dis[T]<inf;
    }
    // 最大流,最小费用
    int maxflow,mincost;
    void mincostflow(){
        maxflow = mincost = 0;
        while(spfa()){
            int tmp = inf;
            for(int i=T;i!=S;i=e[from[i]].u)tmp = min(tmp,e[from[i]].f);
            maxflow+=tmp;mincost+=tmp*dis[T];
            for(int i=T;i!=S;i=e[from[i]].u)e[from[i]].f-=tmp,e[from[i]^1].f+=tmp;
        }
    }
}Minicostflow;

signed main(){
    in(n);in(m);in(Minicostflow.S);in(Minicostflow.T);Minicostflow.n=n;
    for(int u,v,f,c,i=1;i<=m;i++){
        in(u);in(v);in(f);in(c);
        Minicostflow.add(u,v,f,c);
    }
    Minicostflow.mincostflow();
    o(Minicostflow.maxflow);putchar(' ');
    o(Minicostflow.mincost);putchar('\n');
//    o(MAXF.cal());putchar('\n');
    return 0;
}
原文地址:https://www.cnblogs.com/yesuweiYYYY/p/15527951.html