算法引入:
任何容量網絡的最大流流量是唯一且確定的,但是它的最大流f並不是唯一的;
既然最大流f不唯一,因此,如果每條弧上不僅有容量限制,還有費用r;
即每條弧上有一個單位費用的參數,那么在保證最大流的前提下;
還存在一個選擇費用最小的最大流問題,即為最小費用最大流問題;
算法思想:
尋找最大流的方法是從某個可行流出發,找到關於這個流的一條增廣路P;
沿着P調整f,對新的可行流又試圖尋找關於它的增廣路,循環直至不存在增廣路為止;
要求最小費用最大流:
如果f是流量為f1的可行流中費用最小者,而p是關於f的所有增廣路中費用最小的增廣路;
那么沿着p去調整f,得到可行流_f,就是流量為f1的所有可行流中的費用最小者;
這樣當f是最大流時,它也就是所要求的最小費用最大流了;

1 const int N=1100,INF=0x3f3f3f3f; 2 const int M=N*N; 3 int pre[N],d[N],p[N],ans; 4 int cnt,head[N]; 5 int q[M],l,r; 6 struct edge 7 { 8 int u,v,w,c,next; 9 }e[M]; 10 void init() 11 { 12 memset(head,-1,sizeof(head)); 13 ans=cnt=0; 14 } 15 void add(int u,int v,int w,int c) 16 { 17 e[cnt].u=u,e[cnt].v=v,e[cnt].w=w,e[cnt].c=c; 18 e[cnt].next=head[u],head[u]=cnt++; 19 e[cnt].u=v,e[cnt].v=u,e[cnt].w=-w,e[cnt].c=0; 20 e[cnt].next=head[v],head[v]=cnt++; 21 } 22 void updata(int s,int t) 23 { 24 int i,f=INF; 25 for(i=t;i!=s;i=e[pre[i]].u) 26 f=min(f,e[pre[i]].c); 27 for(i=t;i!=s;i=e[pre[i]].u) 28 { 29 e[pre[i]].c-=f; 30 e[pre[i]^1].c+=f; 31 ans+=f*e[pre[i]].w; 32 } 33 } 34 int spfa(int s,int t) 35 { 36 int i,u,v,w; 37 memset(p,0,sizeof(p)); 38 memset(pre,-1,sizeof(pre)); 39 memset(d,0x3f,sizeof(d)); 40 l=r=0; 41 q[++r]=s,p[s]=1,d[s]=0; 42 while(l<r) 43 { 44 p[u=q[++l]]=0; 45 for(i=head[u];i!=-1;i=e[i].next) 46 { 47 v=e[i].v,w=e[i].w; 48 if(e[i].c&&d[v]>d[u]+w) 49 { 50 d[v]=d[u]+w; 51 pre[v]=i; 52 if(!p[v]) 53 { 54 p[v]=1; 55 q[++r]=v; 56 } 57 } 58 } 59 } 60 if(pre[t]==-1) 61 return 0; 62 return 1; 63 } 64 void MiCMaF(int s,int t) 65 { 66 ans=0; 67 while(spfa(s,t)) 68 updata(s,t); 69 }
例題:POJ 2135