现在的位置: 首页 > 综合 > 正文

最小费用最大流

2018年02月11日 ⁄ 综合 ⁄ 共 1621字 ⁄ 字号 评论关闭

有了上一篇文章最大流的基础,理解最小费用最大流就很容易了,但是我还是想了挺久的。当我看到最小费用最大流问题这篇文章,才开始觉悟。于是做了如下实现。

/*
	每次找出最短路径(该路径的单位费用和最小)记录该路径(next数组)
	直到找不出这样一条路径(实际上是没有到达终点的路,因为图中的路是会不停的变动)。我们这里的是Distance[0]>=MAX

*/

#include<iostream>
using namespace std;
#define MAX 1024

int nodes,edges;//节点数和边数
int capacity[MAX][MAX];//节点之间的流量
int cost[MAX][MAX];//节点之间的单位费用

int minCost=0;//统计最小费用
int next[MAX];//为了记录最短路径

int Distance[MAX];//表示每个节点到终点的费用
inline int min(int a,int b)
{
	return a<b?a:b;
}
void resetThePath()//找出最短路径,这里还需优化。
{
	int i,j;
	for(i=0;i<nodes-1;i++)
		Distance[i]=MAX;
	Distance[nodes-1]=0;
	next[nodes-1]=-1;
	
	for(i=nodes-1;i>=0;i--)
	{
		for(j=0;j<nodes;j++)
		{
			if(cost[j][i]!=MAX)
			{
				if(Distance[j]>(Distance[i]+cost[j][i]))
				{
					Distance[j]=Distance[i]+cost[j][i];
					next[j]=i;
				}
			}
		}	
	}

	for(i=nodes-1;i>=0;i--)
	{
		for(j=0;j<nodes;j++)
		{
			if(cost[j][i]!=MAX)
			{
				if(Distance[j]>(Distance[i]+cost[j][i]))
				{
					Distance[j]=Distance[i]+cost[j][i];
					next[j]=i;
				}
		}	
	}	
}

void minCostMaxFlow()
{
	while(1)
	{
		int i;
		resetThePath();
		if(Distance[0]>=MAX)//没有最短路径
			break;
		int increase=MAX;//本次最短路径中的流量
		for(i=0;next[i]!=-1;i=next[i])
		{
			increase=min(increase,capacity[i][next[i]]);
		}
		for(i=0;next[i]!=-1;i=next[i])//改变图的路径信息
		{
			capacity[i][next[i]]-=increase;
			capacity[next[i]][i]+=increase;
			if(cost[next[i]][i]==MAX)
				cost[next[i]][i]=cost[i][next[i]]*(-1);
			if(!capacity[i][next[i]])
				cost[i][next[i]]=MAX;
		}
		minCost+=Distance[0]*increase;
	}		
}

void main()
{
	while(1)
	{
		cin>>nodes>>edges;
		int i,j;
		for(i=0;i<nodes;i++)
		{
			for(j=0;j<nodes;j++)
				capacity[i][j]=0;
			for(j=0;j<nodes;j++)
				cost[i][j]=MAX;
		}
		int firstnode,secondnode,capa,cos;
		for(i=0;i<edges;i++)
		{
			cin>>firstnode>>secondnode>>capa>>cos;
			capacity[firstnode][secondnode]=capa;
			cost[firstnode][secondnode]=cos;
		}
		minCostMaxFlow();
		cout<<minCost<<endl;
	}
}



抱歉!评论已关闭.