最小费用最大流(spfa、EK算法及(构图----尤其重要))

原创 2015年05月31日 10:08:40
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string.h>
#include <queue>
#include <vector>           //poj2195最小费用最大流(spfa、EK算法及(构图----尤其重要))
#define inf 1<<30                      
#define N 210
using namespace std;  //构图时,要建立超级源点和超级汇点,源点u都会和每个人相连,cost[u][x]=0, cap[u][x]=1, 每个房子都会和汇点e相连,cost[x][e]=0, cap[x][e]=1
int mantot, houtot, p[N], dis[N], vis[N], cap[N][N], cost[N][N]; //cap表示容量, cost表示花费, 最小费用相当于最短路,最大流相当于每个人对应于一个房子
queue<int> q;
struct node
{
	int x, y;
}man[N], hou[N];
int fab(int x)
{
	if(x>=0)return x;
	else  return -x;
}
int step(int a, int b)
{
	return fab(man[a].x-hou[b].x)+fab(man[a].y-hou[b].y);
}
void buildmap()
{
	int t, j;
	for(t=0; t<mantot; ++t)  //建立超级源点0, 超级汇点1,其他节点从2开始
	{
		cap[0][t+2]=1;
		cost[0][t+2]=0;
	}
	for(t=0; t<houtot; ++t)  //建立超级汇点
	{
		cap[t+2+mantot][1]=1;
		cost[t+2+mantot][1]=0;
	}
	for(j=0; j<mantot; j++)    //建立人和房子之间的距离,连接起来
	{
		for(t=0; t<houtot; ++t)
		{
			cap[j+2][t+2+mantot]=1;
			cost[j+2][t+2+mantot]=step(j, t);
			cost[t+2+mantot][j+2]=-cost[j+2][t+2+mantot];//注意逆边一定要记得加
		}
	}
	return ;
}
int mpmf()
{
	int s=0, e=1, t, g=mantot+houtot+2, u, f=0, totprice=0, flow;
	while(!q.empty())
		q.pop();
	while(1)
	{
		for(t=0; t<g; ++t)
		{
			dis[t]=inf;
			vis[t]=0;
		}
		dis[s]=0;
		q.push(s);
		vis[s]=1;
		while(!q.empty())     //spfa算法
		{
			u=q.front();
			q.pop();
			vis[u]=0;
			for(t=0; t<g; ++t)
			{
				if(cap[u][t]&&dis[t]>dis[u]+cost[u][t])
				{
					dis[t]=dis[u]+cost[u][t];
					p[t]=u;
					if(!vis[t])
					{
						vis[t]=1;
						q.push(t);
					}
				}
			}
		}
		if(dis[1]==inf)   //已经达到最大流且是最小费用
			break;
		for(t=1, flow=inf; t!=0; t=p[t])  //寻找最小流量
		{
			if(cap[p[t]][t]<flow)
				flow=cap[p[t]][t];
		}
		for(t=1; t!=0; t=p[t])
		{
			cap[p[t]][t]-=flow;
			cap[t][p[t]]+=flow;
		}
		f+=flow;
		totprice+=flow*dis[1];
	}
	return totprice;
}

int main()
{
	int n, m, t, j;
	char a[N][N];
	while(scanf("%d%d", &n, &m)!=EOF)
	{
		if(n==0||m==0)break;
		for(t=0; t<n; ++t)
			scanf("%s", &a[t]);
		mantot=houtot=0;    //人的总数,房子的总数
		memset(cap, 0, sizeof(cap));//注意!!!  初始化,0表示没有办法到达
		for(j=0; j<n; ++j)
		{
			for(t=0; t<m; ++t)
			{
				if(a[j][t]=='H')
				{
					hou[houtot].x=j;
					hou[houtot++].y=t;
				}
				else if(a[j][t]=='m')
				{
					man[mantot].x=j;
					man[mantot++].y=t;
				}
			}
		}
		buildmap();  //建图
		printf("%d\n", mpmf());  //minpricemaxflow最小费用最大流
	}
	return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

poj 2135 最小费用最大流 EK+SPFA

传送门 题意:n个点m条边,从1出发到n,再从n返回1,不走重复的边,求路程最少是多少。 个人心得:无向图的网络流,一开始对于建双边还心存不解,后来想着想着就想明白了,明白了就好。 思路:能从1...

最小费用最大流 spfa() + ek()

/** 一个多月没碰,感觉忘完了…… 最小费就是有多条路可以满足最大流量的情况下所需要的最小费用 把费用改成相反数或改下spfa()的松弛就可最大费了 比如:从北京...
  • zcube
  • zcube
  • 2015年09月05日 10:00
  • 2456

HDU 1533 (最小费用最大流)(spfa+ek或spfa+dinic)

HDU 1533 (最小费用最大流)(spfa+ek或spfa+dinic) 设一个虚拟source和sink,source连man,费用为0,home连sink,费用为0,与source和sink连...

poj 2135 Farm Tour--最小费用最大流--邻接表--构图的时候注意退边--以及退边的算法

/* 题意:n个地点有m条路相连,从1走到n再回来,不走重复的路(这题居然认为,同一条路,按不同的方向走算是走不重复的路) 最小费用最大流 因为要来回,素以相当于找两条1~n的最短路 s~1 流量...

hdoj 1853 Cyclic Tour 【最小费用最大流 or KM算法】【构图后可以判断图中是否存在哈密顿环】

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Tota...

网络流入门 最大流,带下界,最小费用,EK算法,Dinic算法 模板

网络流题目内容有最大流,最小费用,匹配等 基础的是最大流问题,核心在于添加了反向边,让程序有修订的可能 在有向图中边的权值一般+=,因为可能有多条路。 正向边的数值为可以通过的最大量,反向同义。 ...

poj 2516 Minimum Cost(最小费用最大流 spfa算法求最短路)

题意:有N个店主,M个供应商,K种物品。每个供应商对每种物品的的供应量已知,每个店主对每种物品的需求量的已知,从不同的供应商运送不同的货物到不同的店主手上需要不同的花费,又已知从供应商Mj送第kind...

【图论】最大流之EK算法与Dinic算法及最小费用最大流

最大流: 给出一张网络图,并指定源点和终点,每条边都有它的容量,起点有着无限的流量,求从源点到经过的所有路径的最终到达汇点的最大流量和。对于同一个节点,流入的流量之和和流出的流量之和相同,即假如结点1...

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

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

POJ 2195:Going Home(SPFA最小费用最大流)

B - Going Home Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:最小费用最大流(spfa、EK算法及(构图----尤其重要))
举报原因:
原因补充:

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