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.
InputThere 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.
OutputFor 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 Out12
题意:输入一个n行m列的图,‘H’和'm'数目相等,从‘m’出发到'H',走一步花费加1,问,在满足每个'm'都能走到'H'的情况下,求出
总的最小花费。
思路:求最小匹配,我们可以转换思路,用一个总的值sum-最大匹配,就是我们要求的最小匹配,比如说,我们要求一个集和中的
最小值min,那么我们用一个max减去集合中每一个数,再求出集合的最大值max2,我们所求的min = max-max2。
那么这道题中呢,只是把求最小值换为求最小和,我们同样可以用总和-最大和求得。(为什么让我想起了上次的最大子段和~~)
这个思路转换过来后,它就是一个km模板的套路题了。
~~~早起鸟儿果然有虫吃,又get到一个新技能,自己这道题一开始求得最大匹配,后来发现无法求出最小匹配,后来看了别人的博客才知道
可以建图的时候转换一下,不过最大的收获就是我的模板又得到了优化,之前是slack数组去存每一个不在交错树中的tmp值,最后还要
进行比较得出最小常数d,现在呢,就完全不用了,我们直接定义一个全局d,每次dfs的时候都更新一遍,就不用像之前那样处理
不在交错树中的slack值
#include<stdio.h> #include<string.h> #define N 110 #define INF 0x3f3f3f3f int n,m; char map[N][N]; int sumhome,summan; int w[N][N],linker[N]; int lx[N],ly[N],visx[N],visy[N]; int ans,d,nx,ny; struct node{ int x,y; }; node home[N],man[N]; int abs(int a)//取绝对值 { if( a < 0) return -a; return a; } void Count()//编号 { int i,j; sumhome = summan = 0; for(i = 1; i <= n; i ++) for(j = 1; j <= m; j ++) { if(map[i][j] == '