最小费用最大流

原创 2012年03月31日 00:01:17

最小费用最大流就是指网络最大流的集合中找出最小费用的那个最大流。

其基本思想是从某个可行流F出发,找到关于这个流的一个可改进路经P,然后沿着P调整F,对新的可行流试图寻找关于他的可改进路经,如此反复直至求得最大流。现在要找最小费用的最大流,可以证明,若F是流量为V(F)的流中费用最小者,而P是关于F的所有可改进路中费用最小的可改进路,则沿着P去调整F,得到的可行流F'一定是流量为V(F')的所有可行流中的最小费用流。这样,当F是最大流时候,他就是所要求的最小费用最大流。


f是正向流,并且f没有饱和,则还可以继续增加正向流,所有构件的新的残余网络是正向的边,权重是正的单位花费,同时也可以减少f,对应的是反向边,权重是负的单位花费;

f是饱和流,对于新的残余网络,只构件反向边,权重是负的单位花费

f=0,只构件正向边,权重是正的单位花费


整体架构就是用spfa,获得最短增量链

用ff调整流

poj2195:


#include <cstring>
#include <iostream>
#include <vector>
#include <cmath>
#include <queue>
#include <limits>
#include <stdio.h>
#include <set>


using namespace std;


struct pos{
int i;
int j;
};
int N;
int M;
//char maphm[100][100];
const int maxNode = 202;
//int residal[maxNode][maxNode];//maxInt表示此路不通
//int residalf[maxNode][maxNode];
int capital[maxNode][maxNode];//还剩余的空间[i][j]表示i-->j的剩余容量,[j][i]表示j--->i的剩余容量
//int flow[maxNode][maxNode];
int maxTime[maxNode];
int pre[maxNode];
int minCost[maxNode];//从0到i结点的最小花费
int maxRealNode;
int maxInt = numeric_limits<int>::max();
int costMtx[maxNode][maxNode];//单位花费


bool spfa()
{
memset(maxTime,0,sizeof(maxTime));
memset(pre,-1,sizeof(pre));
queue<int> q;
//set<int> s;
bool vsd[maxNode];
memset(vsd,false,sizeof(vsd));
vsd[0] = true;
q.push(0);
minCost[0] = 0;
++maxTime[0];
for(int i=1;i<maxRealNode;++i)
minCost[i] = maxInt;
while (!q.empty())
{
int node = q.front();
q.pop();
vsd[node] = false;
for (int i = 0;i<maxRealNode;++i)
{

if(capital[node][i] && minCost[i] >(minCost[node]+ costMtx[node][i]))//1.如果从node-->i还有容量,即使是负向的容量;2.minCost[node]<maxInt,因为都是在得到较小值后放入队列中
{
if(maxTime[i]+1>=maxRealNode)
return false;
++maxTime[i];
if(!vsd[i])
{
q.push(i);
vsd[i] = true;
}
minCost[i] = minCost[node]+costMtx[node][i];
pre[i] = node;
}
}

}
if(minCost[maxRealNode -1]<maxInt)
return true;
return false;
}


int min_cost_max_flow()
{
int minCostAll = 0;
while(spfa())
{

int e = maxRealNode -1;
int minFlow = maxInt;
while (e>0)
{
int preNode = pre[e];
if(minFlow >capital[preNode][e])
minFlow = capital[preNode][e];
e = preNode;
}


e = maxRealNode - 1;
while (e >0)
{
int preNode = pre[e];
capital[preNode][e] -=minFlow;
capital[e][preNode] +=minFlow;
minCostAll +=minFlow * costMtx[preNode][e];


e = preNode;
}


}


return minCostAll;
}


int cost(pos &p1,pos &p2)//m,h
{
return abs((float)(p1.i-p2.i)) + abs((float)(p1.j-p2.j));
}


int main()
{
//while(cin>>N>>M)
while(scanf("%d%d",&N,&M)!=EOF)
{
//cout<<N<<" "<<M<<endl;


if(N==0 && M==0)
return 0;
char t;
vector<pos> m;
vector<pos> h;
for (int i=0;i<N;++i)
{
for (int j=0;j<M;++j)
{
cin>>t;
pos post;
post.i = i;
post.j = j;
if(t=='H')
h.push_back(post);
else if(t =='m')
m.push_back(post);
}
}



memset(capital,0,sizeof(capital));
//memset(residal,0,sizeof(residal));
//memset(flow,0,sizeof(flow));
memset(costMtx,0,sizeof(costMtx));
//memset(residalf,0,sizeof(residalf));



int mNum = m.size();
int hNum = h.size()+mNum;
maxRealNode = hNum+2;




for (int i=1;i<=mNum;++i)//0->i的容量
{
capital[0][i] = 1;
}
for(int i=mNum+1;i<=hNum;++i)//i-->end的容量
capital[i][hNum+1] = 1;


for (int i=0;i<m.size();++i)
{
for (int j=0;j<h.size();++j)
{
capital[i+1][mNum+1+j] = 1;
costMtx[i+1][mNum+1+j] = cost(m[i],h[j]);
costMtx[mNum+1+j][i+1]= -costMtx[i+1][mNum+1+j];
}
}

cout<<min_cost_max_flow()<<endl;


}
/*scanf("%d%d",&N,&M);
cout<<N<<" "<<M<<endl;*/


return 0;
}





最小费用最大流matlab代码

  • 2014年09月25日 10:54
  • 37KB
  • 下载

最小费用最大流C++算法

  • 2014年04月12日 16:08
  • 10KB
  • 下载

POJ2195 Going Home(最小费用最大流模板题)(附用数组建图和用链式前向星建图代码)

Going HomeTime Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%lld & %llu SubmitStatusPrac...
  • llzhh
  • llzhh
  • 2016年11月07日 21:09
  • 410

最大流最小费用数据

  • 2016年08月07日 11:13
  • 7.99MB
  • 下载

数学建模的最大流和最小费用流

  • 2010年09月07日 19:54
  • 445KB
  • 下载

poj 2135 Farm Tour 【无向图最小费用最大流】

题目:poj 2135 Farm Tour  题意:给出一个无向图,问从 1 点到 n 点然后又回到一点总共的最短路。 分析:这个题目不读仔细的话可能会当做最短路来做,最短路求出来...

AMPL 最小费用最大流模型

  • 2013年01月06日 01:48
  • 776B
  • 下载

最大流,最小费用流,着色

  • 2017年08月20日 22:36
  • 44KB
  • 下载

Acme Corporation UVA - 11613 (最小费用最大流)题解

Acme Corporation UVA - 11613 (最小费用最大流)题解

最小费用最大流(讲解+模板)

         问题引入:最小费用最大流问题是经济学和管理学中的一类典型问题。在一个网络中每段路径都有“容量”和“费用”两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择路径、...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:最小费用最大流
举报原因:
原因补充:

(最多只允许输入30个字)