POJ 2195 Going Home 【二分图最小权值匹配】
传送门:http://poj.org/problem?id=2195
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 26151 | Accepted: 13117 |
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
Sample Input
2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0
Sample Output
2
10
28
题意概括:
给一个长为 H 宽为 W 的地图,地图上 m 代表人, H 代表家,求所有人回到家的最小权值之和。(人到家的距离为 哈密顿距离)
解题思路:
拆点建二分图,距离反转,KM算法求二分图的最大权值匹配,那么去掉负号最大的就是最小的权值之和了。
AC code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = ; char str[MAXN][MAXN];
int c[MAXN][MAXN];
int ex[MAXN], ey[MAXN];
bool visx[MAXN], visy[MAXN];
int match[MAXN];
int HH, WW;
int numx, numy; struct date
{
int x, y;
}M[MAXN], H[MAXN]; bool dfs(int x)
{
visx[x] = true; for(int y = ; y < numx; y++){
if(!visy[y] && ex[x]+ey[y]-c[x][y] == ){
visy[y] = true; if(match[y] == - || dfs(match[y])){
match[y] = x;
return true;
}
}
}
return false;
} void KM()
{
memset(ey, , sizeof(ey));
memset(match, -, sizeof(match)); for(int i = ; i < numx; i++){
ex[i] = c[i][];
for(int j = ; j < numx; j++){
if(c[i][j] > ex[i])
ex[i] = c[i][j];
}
} for(int i = ; i < numx; i++){
while(){
memset(visx, , sizeof(visx));
memset(visy, , sizeof(visy)); if(dfs(i)) break; int d = INF;
for(int j = ; j < numx; j++){
if(visx[j]){
for(int k = ; k < numx; k++){
if(!visy[k] && ex[j]+ey[k]-c[j][k] < d)
d = ex[j] + ey[k] - c[j][k];
}
}
} for(int j = ; j < numx; j++){
if(visx[j]) ex[j]-=d;
if(visy[j]) ey[j]+=d;
}
}
} int res = ;
for(int i = ; i <numx; i++){
res+=c[match[i]][i];
}
printf("%d\n", -res);
} int main()
{
while(~scanf("%d %d", &HH, &WW) && (HH+WW)){
numx = numy = ;
for(int i = ; i < HH; i++){
scanf("%s", &str[i]); for(int j = ; j < WW; j++){
if(str[i][j] == 'm'){
M[numx].x = i;
M[numx++].y = j;
}
else if(str[i][j] == 'H'){
H[numy].x = i;
H[numy++].y = j;
}
}
} for(int i = ; i < numx; i++){
for(int j = ; j < numx; j++)
c[i][j] = -(abs(M[i].x - H[j].x) + abs(M[i].y - H[j].y));
}
KM();
}
return ;
}
POJ 2195 Going Home 【二分图最小权值匹配】的更多相关文章
- POJ-2195 Going Home---KM算法求最小权值匹配(存负边)
题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...
- POJ 3565 Ants 【最小权值匹配应用】
传送门:http://poj.org/problem?id=3565 Ants Time Limit: 5000MS Memory Limit: 65536K Total Submissions: ...
- ZOJ-2342 Roads 二分图最小权值覆盖
题意:给定N个点,M条边,M >= N-1.已知M条边都有一个权值,已知前N-1边能构成一颗N个节点生成树,现问通过修改这些边的权值使得最小生成树为前N条边的最小改动总和为多少? 分析:由于计算 ...
- UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi ...
- 紫书 例题11-10 UVa 1349 (二分图最小权完美匹配)
二分图网络流做法 (1)最大基数匹配.源点到每一个X节点连一条容量为1的弧, 每一个Y节点连一条容量为1的弧, 然后每条有向 边连一条弧, 容量为1, 然后跑一遍最大流即可, 最大流即是最大匹配对数 ...
- UVA 1349 Optimal Bus Route Design (二分图最小权完美匹配)
恰好属于一个圈,那等价与每个点有唯一的前驱和后继,这让人想到了二分图, 把一个点拆开,点的前驱作为S集和点的后继作为T集,然后连边,跑二分图最小权完美匹配. 写的费用流..最大权完美匹配KM算法没看懂 ...
- POJ 2404 Jogging Trails(最小权完美匹配)
[题目链接] http://poj.org/problem?id=2404 [题目大意] 给出一张图,求走遍所有的路径至少一次,并且回到出发点所需要走的最短路程 [题解] 如果图中所有点为偶点,那么一 ...
- POJ 2195 Going Home (带权二分图匹配)
POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...
- [ACM] POJ 3686 The Windy's (二分图最小权匹配,KM算法,特殊建图)
The Windy's Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4158 Accepted: 1777 Descr ...
随机推荐
- oracle 集群RAC搭建--环境准备
一,环境介绍 目前我本身环境已经有DG,正在尝试重做搭建.如需完成请移步往期文章--搭建DG
- 利用wireshark和python分析网络
- Android:Sqlitedatabase学习小结
今天刚刚学习完Sqlite数据库的基础知识,随即把学到的东西记录下来,以便随后查阅,以下是自己对Sqlite数据库的小结:1.Sqlite简介 Sqlite是一款轻型的数据库,它包含在一个 ...
- zookeeper简单命令
bin/zkCli.sh -server ls / create /zk_test my_data get /zk_test set /zk_test admln delete /zk_test ad ...
- [转]MVC+JQuery validate实现用户输入验证
本文转自:http://www.cnblogs.com/ahui/archive/2010/10/08/1845677.html MVC服务器端: 1.在controller中验证用户输入,如果验证失 ...
- Windows phone 8.1应用集成cortana语音命令
微软推出小娜已经有一段时间了,最近恰好在研究其用法,就随便写点记录一下自己的心得. 在研究时参考了@王博_Nick的博客:http://www.cnblogs.com/sonic1abc/p/3868 ...
- C# 获取字符串长度
int leng = System.Text.Encoding.Default.GetBytes(attachfileId2).Length;
- Machine Learning的定义
---恢复内容开始--- 所下内容都是对吴恩达教授的机器学习所做的笔记 下面是Arthur Samue对机器学习的定义 在没有明确设置的情况下,是计算机具有学习能力的研究领域. 这是一个比较陈旧一点的 ...
- initBinder转换日期格式
@Controller public class FirstController { @RequestMapping("/first") //类型转化工作一定是在真正的handle ...
- 项目在低版本浏览器下不兼容?友情提示客户升级浏览器(以下只针对IE浏览器)
(function (window) { var win = window, sys = {}, ua = navigator.userAgent.toLowerCase(); (/msie\s+(\ ...