最小费用最大流


网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素。网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w)。对于网络中一个给定的流flow,其费用定义为:

网络流定义.jpg 


最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小。

求解MCMF问题的算法: 在这里各种算法的证明以及原理的详解不再赘述,仅仅介绍算法的过程。相关内容感兴趣的同学可以自己去搜索资料。 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直至找到最小费用流。 残流网络中边的费用定义为:

MCMF.jpg 


当残流网络中边(v,w)是向前边时,其费用为cost(v,w); 当(v,w)是向后边时,其费用为-cost(w,v)。

最小费用流的最小费用路算法

步骤0:初始可行0流。  步骤1:如果不存在最小费用路,则计算结束,已经找到最小费用流;否则用最短路算法在残流网络中找从s到t的最小费用可增广路,转步骤2。  步骤2:沿找到的最小费用可增广路增流,并转步骤1。 

最小费用路算法的复杂度主要依靠于求最短路的方法,由于负权的存在,不会选择dijstra等算法,一般bellman-ford,spfa等用来解决费用流的最短路问题。

 

 

模版题:

POJ 2135

代码: 

 

View Code 
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5  using  namespace std;
  6  int sumFlow;
  7  const  int MAXN =  1010;
  8  const  int MAXM =  1000200;
  9  const  int INF =  1000000000;
 10  struct Edge
 11 {
 12      int u;
 13      int v;
 14      int cap;
 15      int cost;
 16      int next;
 17 }edge[MAXM<< 2];
 18  int NE;
 19  int head[MAXN], dist[MAXN], pp[MAXN];
 20  bool vis[MAXN];
 21  void init()
 22 {
 23     NE= 0;
 24     memset(head,- 1, sizeof(head));
 25 }
 26  void addedge( int u, int v, int cap, int cost)
 27 {
 28     edge[NE].u=u;edge[NE].v=v;edge[NE].cap=cap;edge[NE].cost=cost;
 29     edge[NE].next=head[u];head[u]=NE++;
 30     edge[NE].u=v;edge[NE].v=u;edge[NE].cap= 0;edge[NE].cost=-cost;
 31     edge[NE].next=head[v];head[v]=NE++;
 32 }
 33  bool SPFA( int s, int t, int n)
 34 {
 35      int i,u,v;
 36     queue< int>qu;
 37     memset(vis, false, sizeof(vis));
 38     memset(pp,- 1, sizeof(pp));
 39      for(i= 0;i<=n;i++) 
 40         dist[i]=INF;
 41     vis[s]= true;
 42     dist[s]= 0;
 43     qu.push(s);
 44      while(!qu.empty())
 45     {
 46         u=qu.front();
 47         qu.pop();
 48         vis[u]= false;
 49          for(i=head[u];i!=- 1;i=edge[i].next)
 50         {
 51             v=edge[i].v;
 52              if(edge[i].cap&&dist[v]>dist[u]+edge[i].cost)
 53             {
 54                 dist[v]=dist[u]+edge[i].cost;
 55                 pp[v]=i;
 56                  if(!vis[v])
 57                 {
 58                     qu.push(v);
 59                     vis[v]= true;
 60                 }
 61             }
 62         }
 63     }
 64      if(dist[t]==INF) 
 65          return  false;
 66      return  true;
 67 }
 68  int MCMF( int s, int t, int n)
 69 {
 70      int flow= 0//  总流量
 71       int i,minflow,mincost;
 72     mincost= 0;
 73      while(SPFA(s,t,n))
 74     {
 75         minflow=INF+ 1;
 76          for(i=pp[t];i!=- 1;i=pp[edge[i].u])
 77              if(edge[i].cap<minflow)
 78                 minflow=edge[i].cap;
 79         flow+=minflow;
 80          for(i=pp[t];i!=- 1;i=pp[edge[i].u])
 81         {
 82             edge[i].cap-=minflow;
 83             edge[i^ 1].cap+=minflow;
 84         }
 85         mincost+=dist[t]*minflow;
 86     }
 87     sumFlow=flow;  //  最大流
 88       return mincost;
 89 }
 90  int main()
 91 {
 92      int n,m;
 93      int u,v,c;
 94      while(~scanf( " %d%d ",&n,&m))
 95     {
 96         init();
 97          int S= 0;
 98          int T=n+ 1;
 99          while(m--)
100         {
101             scanf( " %d%d%d ",&u,&v,&c);
102             addedge(u,v, 1,c);
103             addedge(v,u, 1,c);
104         }
105         addedge(S, 1, 2, 0);
106         addedge(n,T, 2, 0);
107          int ans=MCMF(S,T,T+ 1);
108         printf( " %d\n ",ans);
109     }
110      return  0;
111 }
112

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM