YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最小费用流最大流问题指的是在一个网络流网络中,每条边有两个权值,分别指的是该边的流量上限和流入流量需要的费用。问当流入的流量为f时,最少需要多少的费用。这中问题称为最小费用流问题,当f=最大流时,称为最小费用流最大流问题。

最小费用流最大流:(洛谷的一个模板题

code:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int n,m,s,t;
const int INF=1e9+7;
struct stu{
    int to,val,cost,nxt;
}edge[N];
int ans1=0,ans2=0;
int tol=0,head[N];
void add(int x,int y,int z,int cos){
    edge[tol].to=y;
    edge[tol].val=z;
    edge[tol].cost=cos;
    edge[tol].nxt=head[x];
    head[x]=tol++;
}
int num[N],mark[N],dis[N],pre[N];
bool spfa(){
    for(int i=1;i<=n;i++) {
        dis[i]=INF;
        pre[i]=0;
        num[i]=0;
        mark[i]=0;
    }
    queue<int >que;
    que.push(s);
    mark[s]=1;
    dis[s]=0;
    num[s]++;
    while(que.size()){
        int u=que.front();
        que.pop();
        mark[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            int w=edge[i].cost;
            if(edge[i].val>0&&dis[v]>dis[u]+w){
                dis[v]=dis[u]+w;
                pre[v]=i;
                if(mark[v]==0){
                    mark[v]=1;
                    que.push(v);
                    if(num[v]>n) return 0;
                }
            }
        }
    }
    return dis[t]!=INF;
}
void min_cost(){
    int x=t;
    int minn=INF;
    while(x!=s){
        int v=pre[x];
        minn=min(minn,edge[v].val);
        x=edge[v^1].to;
    }
    ans1+=dis[t]*minn;
    ans2+=minn;
    x=t;
    while(x!=s){
        int v=pre[x];
        edge[v].val-=minn;
        edge[v^1].val+=minn;
        x=edge[v^1].to;
    }
}
int main(){
    memset(head,-1,sizeof head);
    scanf("%d%d%d%d",&n,&m,&s,&t);
    int u,v,w,f;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d%d",&u,&v,&w,&f);
        add(u,v,w,f);
        add(v,u,0,-f);
    }
    while(spfa()){
        min_cost();
    }
    printf("%d %d\n",ans2,ans1);
    return 0;
}

 

posted on 2020-07-23 14:52  Target--fly  阅读(321)  评论(0编辑  收藏  举报