最小费用最大流

转自pony1993

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素。网络的每一条边(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<cstdio>
  3 #include<cstring>
  4 #include<stdlib.h>
  5 #include<queue>
  6 using namespace std;
  7 #define INF 0xfffffff
  8 struct node
  9 {
 10     int u,v,cap,cost,next;
 11 }edge[40010];
 12 int head[1010],dist[1010],pp[1010],t,vis[1010];
 13 void init()
 14 {
 15     t = 0;
 16     memset(head,-1,sizeof(head));
 17 }
 18 void add(int u,int v,int c,int p)
 19 {
 20     edge[t].u = u;
 21     edge[t].v = v;
 22     edge[t].cap = c;
 23     edge[t].cost = p;
 24     edge[t].next = head[u];
 25     head[u] = t++;
 26     edge[t].v = u;
 27     edge[t].u = v;
 28     edge[t].cap = 0;
 29     edge[t].cost = -p;
 30     edge[t].next = head[v];
 31     head[v] = t++;
 32 }
 33 int spfa(int s,int en,int n)
 34 {
 35     int i,u,v;
 36     queue<int>q;
 37     memset(vis,0,sizeof(vis));
 38     memset(pp,-1,sizeof(pp));
 39     for(i = 0 ; i <= n ; i++)
 40         dist[i] = INF;
 41     dist[s] = 0;
 42     q.push(s);
 43     vis[s] = 1;
 44     while(!q.empty())
 45     {
 46         u = q.front();
 47         q.pop();
 48         vis[u] = 0;
 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                     q.push(v);
 59                     vis[v] = 1;
 60                 }
 61             }
 62         }
 63     }
 64     if(dist[en]==INF)
 65        return 0;
 66     return 1;
 67 }
 68 int mcmf(int s,int en,int n)
 69 {
 70     int flow = 0,i,minf,minc=0;
 71     while(spfa(s,en,n))
 72     {
 73         minf = INF+1;
 74         for(i = pp[en] ; i!=-1 ; i = pp[edge[i].u])
 75         {
 76             if(edge[i].cap<minf)
 77             minf = edge[i].cap;
 78         }
 79         flow+=minf;
 80         for(i = pp[en]; i!=-1 ; i = pp[edge[i].u])
 81         {
 82             edge[i].cap-=minf;
 83             edge[i^1].cap += minf;
 84         }
 85         minc += minf*dist[en];
 86     }
 87 
 88     return minc;
 89 }
 90 int main()
 91 {
 92     int i,j,k,n,m,u,v,c;
 93     while(cin>>n>>m)
 94     {
 95         init();
 96         int s = 0;
 97         int en = n+1;
 98         for(i = 1; i <= m ;i++)
 99         {
100             scanf("%d%d%d",&u,&v,&c);
101             add(u,v,1,c);
102             add(v,u,1,c);
103         }
104         add(s,1,2,0);
105         add(n,en,2,0);
106         cout<<mcmf(s,en,n+1)<<endl;;
107     }
108     return 0;
109 }

 

 

posted @ 2013-03-18 20:31  _雨  阅读(508)  评论(0编辑  收藏  举报