在最大流有多組解時,給每條邊在附上一個單位費用的量,問在知足最大流時的最小費用是多少?node
來搞清楚一些概念:ios
其實,就瞭解,解決最小費用最大流問題有兩種思路:算法
通常使用第二種算法,有興趣的同窗能夠自學第一種;網絡
給出一個容量網絡,那他的最大流必定是一個定值(即便是有多個同樣的最大值)。因此咱們從開始的可行流開始增廣時,最終的增廣量是必定的。因此爲了知足最小費用咱們只須要每次找最小費用的增廣路便可,直到流量爲最大值。這個問題僅僅是在求增廣路時先考慮費用最小的增廣路,其餘思想和EK思想同樣。spa
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define N 5010 #define M 50010 #define INF 0x3f3f3f3f using namespace std; int n,m,ss,tt; queue<int>q; int dis[N],minv[N]; bool vis[N]; struct Edge{int to;int value;int cost;int next;}e[M<<1]; struct Pre{int id;int node;}pre[M<<1]; int head[N],cnt=-1; void add(int from,int to,int value,int cost) { cnt++; e[cnt].to=to; e[cnt].value=value; e[cnt].cost=cost; e[cnt].next=head[from]; head[from]=cnt; } bool spfa(int s,int t) { q=queue<int>(); memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(pre,-1,sizeof(pre)); memset(minv,0x3f,sizeof(minv)); dis[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int i=head[x];i>-1;i=e[i].next) { int now=e[i].to; if(dis[now]>dis[x]+e[i].cost&&e[i].value) { dis[now]=dis[x]+e[i].cost; minv[now]=min(minv[x],e[i].value); pre[now].id=i; pre[now].node=x; if(!vis[now]) { vis[now]=1; q.push(now); } } } } return dis[t]!=INF; } void MCMF(int s,int t,int &maxflow,int &mincost) { while(spfa(s,t)) { for(int i=t;i!=s;i=pre[i].node) { e[pre[i].id].value-=minv[t]; e[pre[i].id^1].value+=minv[t]; } maxflow+=minv[t]; mincost+=minv[t]*dis[t]; } } int main() { memset(head,-1,sizeof(head)); scanf("%d%d%d%d",&n,&m,&ss,&tt); for(int i=1;i<=m;i++) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); add(a,b,c,d); add(b,a,0,-d); } int mf=0,mc=0; MCMF(ss,tt,mf,mc); printf("%d %d\n",mf,mc); return 0; }