最小费用最大流模板
算法引入:
任何容量网络的最大流流量是唯一且确定的,但是它的最大流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