HDU 1533:Going Home(KM算法求二分图最小权匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=1533
Going Home
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point. 
You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
Sample Output
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 105
#define INF 0x3f3f3f
char maze[N][N];
int mp[N][N],match[N],lx[N],ly[N],visx[N],visy[N],slack[N];
int n,m,cnt;
struct node
{
int a,b;
}sa[N],sb[N];
//KM求二分图最小匹配模板:只需把权值都变成负的,再用KM算出最大权匹配,然后取反就是答案
//学习KM地址:http://blog.sina.com.cn/s/blog_691ce2b701016reh.html
bool dfs(int x)
{
visx[x]=;
for(int y=;y<=cnt;y++){
if(visy[y]) continue;
int t=lx[x]+ly[y]-mp[x][y];
if(t==){
visy[y]=;
if(match[y]==-||dfs(match[y])){
match[y]=x;
return true;
}
}
else if(slack[y]>t) slack[y]=t;
}
return false;
} int KM()
{
memset(match,-,sizeof(match));
memset(lx,-INF,sizeof(lx));
memset(ly,,sizeof(ly));
for(int i=;i<=cnt;i++){
for(int j=;j<=cnt;j++){
if(mp[i][j]>lx[i]) lx[i]=mp[i][j];
}
}
for(int i=;i<=cnt;i++){
for(int y=;y<=cnt;y++)
slack[y]=INF;
while(){
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(dfs(i)) break;
int d=INF;
for(int y=;y<=cnt;y++){
if(!visy[y]&&d>slack[y]) d=slack[y];
}
for(int x=;x<=cnt;x++){
if(visx[x]) lx[x]-=d;
}
for(int y=;y<=cnt;y++){
if(visy[y]) ly[y]+=d;
else slack[y]-=d;
}
}
}
int res=;
for(int i=;i<=cnt;i++){
if(match[i]>-) res+=mp[match[i]][i];
}
return res;
} int main()
{
int n,m;
while(~scanf("%d%d",&n,&m)){
if(n+m==) break;
for(int i=;i<=n;i++){
scanf("%s",maze[i]+);
}
int cnt1=,cnt2=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(maze[i][j]=='m'){
sa[++cnt1].a=i;
sa[cnt1].b=j;
}
if(maze[i][j]=='H'){
sb[++cnt2].a=i;
sb[cnt2].b=j;
}
}
}
cnt=cnt1;
for(int i=;i<=cnt1;i++){
for(int j=;j<=cnt2;j++){
mp[i][j]=abs(sa[i].a-sb[j].a)+abs(sa[i].b-sb[j].b);
mp[i][j]=-mp[i][j];
}
}
printf("%d\n",-KM());
}
return ;
}
HDU 1533:Going Home(KM算法求二分图最小权匹配)的更多相关文章
- [ACM] HDU 1533 Going Home (二分图最小权匹配,KM算法)
		
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
 - [ACM] POJ 3686 The Windy's (二分图最小权匹配,KM算法,特殊建图)
		
The Windy's Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4158 Accepted: 1777 Descr ...
 - HDU 1533 二分图最小权匹配 Going Home
		
带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配. 最后再把答案取一下反即可. #include <iostream> #include <cst ...
 - POJ  2195 Going Home 【二分图最小权值匹配】
		
传送门:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
 - UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
		
题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi ...
 - KM算法(二分图的最佳完美匹配)
		
KM算法大概过程: (1)初始化Lx数组为该boy的一条权值最大的出边.初始化Ly数组为 0. (2)对于每个boy,用DFS为其找到一个girl对象,顺路记录下S和T集,并更新每个girl的slac ...
 - poj 3565 uva 1411 Ants KM算法求最小权
		
由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...
 - 【POJ 2195】 Going Home(KM算法求最小权匹配)
		
[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
 - poj3565 Ants km算法求最小权完美匹配,浮点权值
		
/** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...
 
随机推荐
- Debian7离线升级bash漏洞—然后修复方法
			
### 昨天还说的传说要又一次出补丁,今天就都出来了.基本操作一致就是測试结果不一样.继续修复 Debian7 wheezy版本号的bash漏洞,例如以下操作: 1.測试是否须要升级 # env x= ...
 - [PHP7.0-PHP7.2]的新特性和新变更
			
php7发布已经升级到7.2.里面发生了很多的变化.本文整理php7.0至php7.2的新特性和一些变化. 参考资料: http://php.net/manual/zh/migration70.new ...
 - mysql数据库编码、字段编码、表编码  专题
			
CREATE DATABASE `mybatis-subject` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin */ 其中的 ...
 - 客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)
			
今天看到CSDN上这么一篇< 彻底放弃没落的MFC,对新人的忠告!>, 作为一个一直在Windows上搞客户端开发的C++程序员,几年前也有过类似的隐忧(参见 落伍的感觉), 现在却有一些 ...
 - Assertion failure in UITableViewCell layoutSublayersOfLayer解决办法
			
iOS6 设备在更新UITableViewCell的时候遇到了 Assertion failure in -[UITableViewCell layoutSublayersOfLayer:], /So ...
 - QDialog在hide()之后,就被销毁的原因
			
一路跟踪源码,关键就是这两句: int QDialog::exec() { Q_D(QDialog); if (d->eventLoop) { qWarning("QDialog::e ...
 - Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅
			
原文:Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅 在前几期中总结分享了Android的前世今生.Android 系统架构和应用组件那些事.带你一起来聊一聊Android开发 ...
 - 用Delphi实现文件下载的几种方法(三种使用控件的方法)
			
有个API就是UrlDownloadToFile.不仅如此,Delphi的一些控件也可以轻松实现下载,如NMHTTP,指定NMHTTP1.InputFileMode := ture; 指定Body为本 ...
 - Dependency Injection 筆記 (3)
			
续上集.接着要来进一步了解的是 DI 的实现技术,也就是注入相依对象的方式.这里介绍的依赖注入方式,又称为「穷人的 DI」(poor man’s DI),因为这些用法都与特定 DI 工具无关,亦即不使 ...
 - [2017.02.05] 阅读《Efficient C++》思维导图