【POJ 2195】 Going Home(KM算法求最小权匹配)

Going Home
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 20303   Accepted: 10297

Description

On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need to pay a $1 travel fee for every
step he moves, until he enters a house. The task is complicated with the restriction that each house can accommodate only one little man.



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

There are one or more test cases in the input. Each case starts with a line giving two integers N and M, where N is the number of rows of the map, and M is the number of columns. The rest of the input will be N lines describing
the map. You may assume both N and M are between 2 and 100, inclusive. There will be the same number of 'H's and 'm's on the map; and there will be at most 100 houses. Input will terminate with 0 0 for N and M.

Output

For each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay.

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

Source

越来越认为KM算法是种非常奇妙的算法,或者说各种图论算法都好奇妙……在或者说 图是一种奇妙的东西。。。一个题可能有多种算法能够解决

这题之前一仅仅用最小费做的,一直以为是唯一的做法。

今天做KM突然发现 这题之前不是做过么……

这题用KM算法会快非常多。并且代码量少一点。

只是思想的算法。没法做什么比較。

题目大意就是一定数量的人和房子。保证人和房子数量同样,要求分配每一个人到相应的房子里,而且人与房子一一相应。问全部人须要移动的最少步数。建图我是把人和房子的坐标用pair存成数组,然后求出每一个人到每一个房子的距离。也就是最初的二分图。

之后用KM求最小权,跟最大权一种套路,仅仅只是建图的时候权值取负,这样求出的最大权事实上绝对值是最小的。换句话说取反回来后,事实上就是所求的解。

代码例如以下:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define fread() freopen("in.in","r",stdin)
#define fwrite() freopen("out.out","w",stdout)
#define Pr pair<int,int> using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const double eps = 1e-8; //二分图
int mp[233][233];
// x顶标 y顶标
int lx[233],ly[233],link[233],slick[233];
bool visx[233],visy[233];
// 人的坐标 房子坐标
Pr human[233],house[233];
//人数 房数
int nm,nh; bool cal(int x)
{
visx[x] = 1;
for(int y = 0; y < nh; ++y)
{
if(visy[y]) continue; int t = lx[x]+ly[y]-mp[x][y];
if(t == 0)
{
visy[y] = 1;
if(link[y] == -1 || cal(link[y]))
{
link[y] = x;
return true;
}
}
else slick[y] = min(slick[y],t);
}
return false;
} int KM()
{
memset(link,-1,sizeof(link)); for(int i = 0; i < nm; ++i)
{
memset(slick,INF,sizeof(slick));
while(1)
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
if(cal(i)) break;
int d = INF; for(int j = 0; j < nh; ++j)
if(!visy[j]) d = min(d,slick[j]); for(int j = 0; j < nm; ++j)
if(visx[j]) lx[j] -= d; for(int j = 0; j < nh; ++j)
if(visy[j]) ly[j] += d;
else slick[j] -= d;
}
} int ans = 0;
for(int i = 0; i < nh; ++i)
if(link[i] != -1) ans += mp[link[i]][i]; return ans;
} int main()
{
int n,m;
char tmp[233]; while(~scanf("%d%d",&n,&m) && (n+m))
{
nm = nh = 0;
for(int i = 0; i < n; ++i)
{
scanf("%s",tmp);
for(int j = 0; j < m; ++j)
if(tmp[j] == 'm') human[nm++] = Pr(i,j);
else if(tmp[j] == 'H') house[nh++] = Pr(i,j);
} memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly)); for(int i = 0; i < nm; ++i)
for(int j = 0; j < nh; ++j)
{
mp[i][j] = -(abs(human[i].first-house[j].first)+abs(human[i].second-house[j].second));
lx[i] = max(lx[i],mp[i][j]);
} printf("%d\n",-KM());
} return 0;
}

【POJ 2195】 Going Home(KM算法求最小权匹配)的更多相关文章

  1. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

  2. poj 3565 uva 1411 Ants KM算法求最小权

    由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...

  3. 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)

    [POJ 2400] Supervisor, Supervisee(KM求最小权匹配) Supervisor, Supervisee Time Limit: 1000MS   Memory Limit ...

  4. hdu1533 Going Home km算法解决最小权完美匹配

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  5. poj 2195(KM求最小权匹配)

    题目链接:http://poj.org/problem?id=2195 思路:我们都知道KM使用来求最大权匹配的,但如果要求最小权匹配,只需把图中的权值改为负值,求一次KM,然后权值和取反即可. ht ...

  6. poj 2195 Going Home (km算法)

    题目链接: http://poj.org/problem?id=2195 解题思路: 把man和home都提取出来,然后算出每个man和home的距离算出来,然后建立匹配图,套用km算法的模板,求最小 ...

  7. POJ-2195 Going Home---KM算法求最小权值匹配(存负边)

    题目链接: https://vjudge.net/problem/POJ-2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致.man每移动一格 ...

  8. [ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

    The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Descr ...

  9. Fixed Partition Memory Management UVALive - 2238 建图很巧妙 km算法左右顶点个数不等模板以及需要注意的问题 求最小权匹配

    /** 题目: Fixed Partition Memory Management UVALive - 2238 链接:https://vjudge.net/problem/UVALive-2238 ...

随机推荐

  1. Vue this.$router.push、replace、go的区别

    1.this.$router.push 描述:跳转到不同的url,但这个方法会向history添加一个记录,点击后会返回到上一个页面 用法 //字符串 this.$router.push('home' ...

  2. 【codeforces 340B】Maximal Area Quadrilateral

    [题目链接]:http://codeforces.com/problemset/problem/340/B [题意] 给你n个点,让你在这里面找4个点构成一个四边形; 求出最大四边形的面积; [题解] ...

  3. Qt之QNetworkProxy(网络代理)

    简述 QNetworkProxy类提供了一个网络层代理. QNetworkProxy提供了配置网络层代理支持Qt网络类的方法.目前支持的类有QAbstractSocket.QTcpSocket.QUd ...

  4. Java8 Lamdba表达式 002

    本篇将讲述lamdba表达式的排序,本例包括一个Player对象的集合[稍后定义],通过每一个player的分数高低对列表的player进行排序.类定义001例如以下 public class Sor ...

  5. spark一些入门资料

    spark一些入门资料 A Scala Tutorial for Java Programmers http://docs.scala-lang.org/tutorials/scala-for-jav ...

  6. hdu_5139 概率问题

    #include<iostream> #include<cstdio> #include<cmath> using namespace std; int main( ...

  7. 33.unique_ptr独享内存智能指针

    #include <iostream> #include <memory> #include <string> #include <vector> us ...

  8. Android 在Android手机上获取其他应用的包名及版本号

    获取Android手机上其他应用的包名及版本号方法有很多,可以通过AAPT从APK包中直接获取,也可以通过代码在手机上获取.显然,对于产品或者用户来说要获取这些信息,在手机上获取更为简便. 下面我们来 ...

  9. Linux 图形文件压缩/解压缩实用程序,归档管理器。

    1.ArkArk是KDE桌面环境默认的归档管理器,支持插件设置,允许你创建一个压缩包,查看压缩文件的内容,解压压缩包的内容到你所选定的目录.它能处理多种格式,包括 tar.gzip.bzip2.zip ...

  10. Python 批处理文本文件、进行查找

    去年换了一部手机,老手机终于光荣退休了,但是里面的便签里还存有很多文字记录,这个手机还不能备份到云,只能将每个便签保留为一个个的文本文件,我想要把所有的文本文件归到一个文本文件中,手动操作太麻烦了,刚 ...