PKu 2195
//PKu 2195 回家 By Loli_con Enail : Loli_con@outlook.com
/*
题目叙述
=========
在一个网格图中,有n个人和n个房子。每一个单位时间,每个小人可以移动一个单位长度,无论水平还是竖直,到临近的点。对于每个人,每移动一步你需要花费1$,直到他移动到他的家,题目限制一个房子仅能住进一个人
你的任务是计算最小花费使得n个人都能住进不同的n个房子。
输入是一张地图,'.'表示空地,'H'表示房子,'m'表示人
你可以认为一个点是足够的大以至于可以同时站上去全部的n个人,当然,一个人也可以站在房子那个点而不进入。
=====================
输入叙述
=====================
多组测试数据。对于每组测试数据
第一行包括两个整数n和m,表示地图是n行m列的。
接下来n行每行m个字符,'.'、'H'、'm'含义如上。2<=n,m<=100,H<=100,
输入数据以0 0结束
=====================
输出叙述
=====================
对于每组测试数据输出一行一个整数最小花费
=====================
样例输入
=====================
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
=====================
样例输出
=====================
2
10
28
=====================
解题报告
=====================
最小费用最大流模版题,KM算法也可解
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#define Max 5005
#define inf 1<<28
using namespace std;
struct kdq
{
int x,y;
}human[Max],house[Max];
int n,m;
int S,T;//源点,汇点
int cost[Max/][Max];//花费
int cap[Max/][Max];//容量
int dis[Max];
int path[Max];
bool visit[Max];
int q[Max*]; int spfa()//最短路
{
int i,j;
for(i=;i<=T;i++)
dis[i]=inf,path[i]=-,visit[i]=;
dis[S]=;
visit[S]=;
int num=,cnt=;
q[num++]=S;
while(num>cnt)
{
int temp=q[cnt++];
visit[temp]=;
for(i=;i<=T;i++)
{
if(cap[temp][i]&&dis[temp]+cost[temp][i]<dis[i])
{
path[i]=temp;
dis[i]=dis[temp]+cost[temp][i];
if(!visit[i])
{
q[num++]=i;
visit[i]=;
}
}
}
}
return dis[T]!=inf;
} int minCost=;
void getMaxFlow()//增广找最大流
{
int maxFlow=inf; while(spfa())
{
int pre=T;
while(path[pre]!=-)
{
maxFlow=min(maxFlow,cap[path[pre]][pre]);
pre=path[pre];
}
pre=T;
minCost+=dis[T]*maxFlow;//最小费用
while(path[pre]!=-)//更新流
{
cap[path[pre]][pre]-=maxFlow;
cap[pre][path[pre]]+=maxFlow;
//minCost+=cost[path[pre]][pre]*maxFlow;
pre=path[pre];
}
}
cout<<minCost<<endl;
return ;
} int getdis(kdq x,kdq y)//两个坐标之间的费用
{
return (abs(x.x-y.x)+abs(y.y-x.y));
}
void build_map(int numm,int numh)//建图
{
int i,j;
for(i=;i<=numm;i++)//计算房子和人之间的费用
for(j=;j<=numh;j++){
cost[i][j+numm]=getdis(human[i],house[j]);
cost[j+numm][i]=-cost[i][j+numm];//负费用用来回流
}
for(i=;i<=numm;i++)//源点到每个人的cap,cost
cap[S][i]=,cost[S][i]=;
for(i=;i<=numh;i++)//房子到汇点的cap,cost
cap[i+numm][T]=;
for(i=;i<=numm;i++)//每个人和房子之间的cap
for(j=;j<=numh;j++)
cap[i][j+numm]=;
}
int main()
{
int i,j,k,l;
char x;
while(scanf("%d%d",&n,&m),(n+m))
{
memset(cap,,sizeof(cap));
memset(cost,,sizeof(cost)); int numm=,numh=;
for(i=;i<=n;i++)
for(j=;j<=m;j++)
{
cin>>x;
if(x=='m'){
human[++numm].x=i;
human[numm].y=j;
}
if(x=='H'){
house[++numh].x=i;
house[numh].y=j;
}
}
S=;
minCost=;
T=numm+numh+;//其实numm==numh。。。。
build_map(numm,numh);
getMaxFlow();
}
return ;
}
PKu 2195的更多相关文章
- 二分图匹配之KM求二分图最佳匹配算法
参考网址:http://blog.163.com/suntroop@yeah/blog/static/17012103120115185927194/ 对于具有二部划分( V1, V2 )的加权完全二 ...
- HDU——PKU题目分类
HDU 模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 ...
- 刘汝佳黑书 pku等oj题目
原文地址:刘汝佳黑书 pku等oj题目[转]作者:小博博Mr 一.动态规划参考资料:刘汝佳<算法艺术与信息学竞赛><算法导论> 推荐题目:http://acm.pku.edu. ...
- POJ 2195 Going Home 最小费用最大流 尼玛,心累
D - Going Home Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- POJ 2195:Going Home(最小费用最大流)
http://poj.org/problem?id=2195 题意:有一个地图里面有N个人和N个家,每走一格的花费是1,问让这N个人分别到这N个家的最小花费是多少. 思路:通过这个题目学了最小费用最大 ...
- poj 2195 KM算法
题目链接:http://poj.org/problem?id=2195 KM算法模板~ 代码如下: #include "stdio.h" #include "string ...
- poj 2195 二分图带权匹配+最小费用最大流
题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...
- Poj(2195),最小费用流,SPFA
题目链接:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- 【解题报告】PKU 2318 TOYS AND PKU 2398 Toy Storage
题目连接: http://poj.org/problem?id=2318 http://poj.org/problem?id=2398 两题类似的题目,2398是2318的升级版. 题目大概是 ...
随机推荐
- JavaScript中concat()方法
concat(参数) 用于数组之间的连接, arrayObject.concat(arrayX,arrayX,......,arrayX) 如: var a = [1,2,3]; document.w ...
- HTTP历程
原文http://www.ruanyifeng.com/blog/2016/08/http.html 1.HTTP/0.9 HTTP是基于TCP/IP协议的应用层协议.它不涉及数据包传输,主要规定了客 ...
- 51nod1265 四点共面
题目链接:51nod 1265 四点共面 四个点构成的三个向量a,b,c共面的充要条件是存在不全为零的实数x,y,z满足x*a+y*b+z*c=0,然后想到线代了.. 其实就是三个向量的混合积为0:( ...
- C#如何通过Socket的方式获取httponly cookie
正常情况下C#可以使用HttpWebRequest.HttpWebResponse和CookieContainer类来获取Cookie,但是当Cookie设置为httponly,我们就不能用上面的方法 ...
- oracle基础学习
一.创建数据库用户 create user myaccount identified by mypassword;(my+account表示 账号,my+password表示 密码) 二.授予用户权限 ...
- expdp/impdp
1.c:\>sqlplus user1/password@db2.sql>create directory dmpdp as 'C:\data';本地创建文件夹,然后dmp文件放到这个文件 ...
- HTML引入外部文件,解决统一管理导航栏问题。
1.IFrame引入,看看下面的代码 <IFRAME NAME="content_frame" width=100% height=30 marginwidth=0 ...
- VC环境配置办法
在VS工程中,添加c/c++工程中外部头文件及库的基本步骤:1.添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录.2.添加文件引用的l ...
- 使用 WinHttp 实现文件下载
#include <Windows.h> #include <Winhttp.h> #pragma comment(lib,"Winhttp.lib") t ...
- IIS 7.5 发布Web 网站步骤
1. 添加删除程序中,点击打开或关闭Window 功能 , 如图 , 勾选: 2. 打开 vs开发工具 控置台程序 , 注册 aspnet_regiis -i 3.设置应用程序域为指定版本 4.设置应 ...