POJ2195 Going Home【KM最小匹配】
题目链接:http://poj.org/problem?id=2195
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions:27287 | Accepted: 13601 |
Description
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.
Input
Output
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define mem(a, b) memset(a, b, sizeof(a))
const int inf = 0x3f3f3f3f;
using namespace std; int n, m;
char map[][];
int lx[], ly[], match[], visx[], visy[], weight[][], slack[]; struct Node
{
int x, y;
}xx[], yy[];
int cnt1, cnt2; int find(int x)
{
visx[x] = ;
for(int j = ; j <= cnt2; j ++)
{
if(!visy[j])
{
int t = lx[x] + ly[j] - weight[x][j];
if(t == )
{
visy[j] = ;
if(match[j] == - || find(match[j]))
{
match[j] = x;
return ;
}
}
else if(slack[j] > t)
slack[j] = t;
}
}
return ;
} int KM()
{
mem(lx, -inf); //最小权 lx初始化为 -inf
mem(ly, ), mem(match, -);
for(int i = ; i <= cnt1; i ++)
for(int j = ; j <= cnt2; j ++)
lx[i] = max(lx[i], weight[i][j]);
for(int i = ; i <= cnt1; i ++)
{
for(int j = ; j <= cnt2; j ++)
slack[j] = inf;
while()
{
mem(visx, ), mem(visy, );
if(find(i))
break;
int d = inf;
for(int j = ; j <= cnt2; j ++)
if(!visy[j] && d > slack[j])
d = slack[j];
for(int j = ; j <= cnt2; j ++)
{
if(!visy[j])
slack[j] -= d;
else
ly[j] += d;
}
for(int j = ; j <= cnt1; j ++)
if(visx[j])
lx[j] -= d;
}
}
int ans = ;
for(int j = ; j <= cnt2; j ++)
if(match[j] != -)
ans += weight[match[j]][j];
return -ans;//返回负值
} int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
if(n == && m == )
break;
getchar();
cnt1 = , cnt2 = ;
for(int i = ; i <= n; i ++)
scanf("%s", map[i] + );
for(int i = ; i <= n; i ++)
for(int j = ; j <= m; j ++)
{
if(map[i][j] == 'm')//存人的点
xx[++ cnt1].x = i, xx[cnt1].y = j;
else if(map[i][j] == 'H')//存房子的点
yy[++ cnt2].x = i, yy[cnt2].y = j;
}
for(int i = ; i <= cnt1; i ++) //KM求最小匹配 边权赋为 负值
for(int j = ; j <= cnt2; j ++)
weight[i][j] = -(abs(xx[i].x - yy[j].x) + abs(xx[i].y - yy[j].y));
int ans = KM();
printf("%d\n", ans);
}
return ;
}
KM算法求最小匹配
POJ2195 Going Home【KM最小匹配】的更多相关文章
- hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Total ...
- HDU 1533 Going Home(KM完美匹配)
HDU 1533 Going Home 题目链接 题意:就是一个H要相应一个m,使得总曼哈顿距离最小 思路:KM完美匹配,因为是要最小.所以边权建负数来处理就可以 代码: #include <c ...
- 【转载】【最短路Floyd+KM 最佳匹配】hdu 2448 Mining Station on the Sea
Mining Station on the Sea Problem Description The ocean is a treasure house of resources and the dev ...
- perl学习之:理解贪婪匹配和最小匹配之间的区别
正则表达式的新手经常将贪婪匹配和最小匹配理解错误.默认情况下,Perl 的正则表达式是“贪婪地”,也就是说它们将尽可能多地匹配字符. 下面的脚本打印出“matched defgabcdef”,因为它尽 ...
- POJ2195 Going Home —— 最大权匹配 or 最小费用最大流
题目链接:https://vjudge.net/problem/POJ-2195 Going Home Time Limit: 1000MS Memory Limit: 65536K Total ...
- Q - Tour - hdu 3488(最小匹配值)
题意:一个王国有N个城市,M条路,都是有向的,现在可以去旅游,不过走的路只能是环(至少也需要有两个城市),他们保证这些城市之间的路径都是有环构成的,现在至少需要走多少路. 分析:因为是有向图所以,而且 ...
- POJ 2516 Minimum Cost(拆点+KM完备匹配)
题目链接:http://poj.org/problem?id=2516 题目大意: 第一行是N,M,K 接下来N行:第i行有K个数字表示第i个卖场对K种商品的需求情况 接下来M行:第j行有K个数字表示 ...
- BZOJ 3399 [Usaco2009 Mar]Sand Castle城堡:贪心【最小匹配代价】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3399 题意: 给你一个数列a,和一个可变换顺序的序列b(数列长度≤25000). a增加一 ...
- 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)
[POJ 2400] Supervisor, Supervisee(KM求最小权匹配) Supervisor, Supervisee Time Limit: 1000MS Memory Limit ...
随机推荐
- 边学边体验django--HttpRequest 对象
每个view函数的第一个参数是一个HttpRequest对象. HttpRequest对象包含当前请求URL的一些信息: 属性 描述 path 请求页面的全路径,不包括域名'/hello/' meth ...
- Share Point安裝
Win7上裝不了WSS(Sharepoint3.3),而安裝SharePoint Foundation 2010時候又由於不能跑PrerequisiteInstaller.exe,很多該裝的組件裝不上 ...
- VS2012 Update 2: 0x80040154 corrupt install when starting the debugger
使用VS2012開發console program ,发现生成32位的exe文件在別的机上不能正确运行,有文章說update1可以解決這個問題,如下 Setup.exe is not a valid ...
- c语言 宏
#代表命令要被预处理器处理#define 定义的宏可以出现在程序的任意位置#define 定义之后的代码都可以使用这个宏 宏是字面量,不占用内存 单步编译预处理器,只进行文本替换,不进行语法检查:gc ...
- python 监听键盘事件
#coding=utf- from tkinter import * root=Tk() def callback(event): print("点击键盘",repr(event. ...
- Ajax请求如何设置csrf_token
1. 方式一 通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送. $.ajax({ url: "/cookie_ajax/", typ ...
- pandas入门之DataFrame
创建DataFrame - DataFrame是一个[表格型]的数据结构.DataFrame由按一定顺序排列的多列数据组成.设计初衷是将Series的使用场景从一维拓展到多维.DataFrame既有行 ...
- MySQL新特性文档型数据库
mongodb在文档型数据库这方面一直做的很好,也发展了很多年,MySQL作为一个比较大众的数据库也慢慢支持了该特性,下面介绍一下MySQL支持文档型数据库的简单操作. 环境: 主机名 IP 系统 软 ...
- Java并发指南16:JUC中常用的Unsafe和Locksupport
原创文章,转载请注明: 转载自并发编程网 – ifeve.com 1. 什么是Fork/Join框架 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个 ...
- 文件转移 互联网组成 路由器 分组交换 交换机 冲突域 网卡 数据帧的发送与接收会带来CPU开销 CPU中断 双网卡切换
https://zh.wikipedia.org/zh-cn/网段 在以太网环境中,一个网段其实也就是一个冲突域(碰撞域).同一网段中的设备共享(包括通过集线器等设备中转连接)同一物理总线,在这一总线 ...