最小费用流最大流问题指的是在一个网络流网络中,每条边有两个权值,分别指的是该边的流量上限和流入流量需要的费用。问当流入的流量为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; }