Going Home

来源:互联网 发布:鸿鹄安知燕雀之志王侯 编辑:程序博客网 时间:2024/04/29 21:36

Going Home

Time Limit:1000MS  Memory Limit:65536K
Total Submit:19 Accepted:6

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.mH.5 5HH..m...............mm..H7 8...H.......H.......H....mmmHmmmm...H.......H.......H....0 0

 

Sample Output

21028

 

Source

Pacific Northwest 2004

 

El’ÌEl

 

 

今天学习了最佳匹配,也就是二分图最大匹配。

先贴一些资料:

 

带权二分图:二分图的每条边(i,j)均带有一个权Wi,j)。一个匹配的权是匹配各边的和。

可行结点标号:是定义在V上的一个实数函数l 满足条件:对于任意x属于X,y属于Y
    l(x)+l(y)
大于或等于w(x,y)l(v)称为结点v的标号。

等式子图:关于标号l的等式子图Gl=(V,El), El={(x,y):l(x)+l(y)=w(x,y)}

 

 

定理:设l G的可行标号,M是等式子图Gl的完美匹配,则MG的最大权匹配。

设有可行标号lEl的一个匹配M
M不是完美匹配时重复下列步骤:
El中寻找M可增广道路,并扩展匹配;
El’,
Ì如果可增广道路不存在,将l改进为l’使得El 1
注意到循环体总是增加M或者El的大小,故算法终止,而且此时MEl的完美匹配,因此是最大权匹配。

1.从一个初始标号l出发,求出El, 然后在其中任取匹配M; 利用Hungarian算法求 El的最大匹配.
2.
如果找到了 El完美匹配,则此匹配是G的完美匹配。
3.
否则,M的一个交互树H不包含可增广道路,不能继续扩展。修改标号l, 使得新标号的等式子图扩展了El, 并且包含了MH, 然后继续扩展H
4.
重复3,直至找到等式子图的完美匹配。

其中涉及到几个概念,二分图,等式子图,匹配图。

二分图根据可行标等于权值得到等式了图,在等式了图上运用匈牙利算法寻找增广轨得到匹配图。

int km()

{

      int i;

      memset(math,-1,sizeof(math));

     for(i=0;i<n;i++)   //每次匹配一个

     {
   memset(visit,0,sizeof(visit));
   while(!dfs(i))
   {
    adjust(i);
    memset(visit,0,sizeof(visit));
   }

     }

}

 

 

KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点Xi的顶标为A[i],顶点Yi的顶标为B[i],顶点XiYj之间的边权为w[i,j]。在算法执行过程中的任一时刻,对于任一条边(i,j)A[i]+B[j]>=w[i,j]始终成立。KM算法的正确性基于以下定理:

  若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。

  这个定理是显然的。因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和。所以相等子图的完备匹配一定是二分图的最大权匹配。

  初始时为了使A[i]+B[j]>=w[i,j]恒成立,令A[i]为所有与顶点Xi关联的边的最大权,B[j]=0。如果当前的相等子图没有完备匹配,就按下面的方法修改顶标以使扩大相等子图,直到相等子图具有完备匹配为止。

  我们求当前相等子图的完备匹配失败了,是因为对于某个X顶点,我们找不到一条从它出发的交错路。这时我们获得了一棵交错树,它的叶子结点全部是X顶点。现在我们把交错树中X顶点的顶标全都减小某个值dY顶点的顶标全都增加同一个值d,那么我们会发现:

两端都在交错树中的边(i,j)A[i]+B[j]的值没有变化。也就是说,它原来属于相等子图,现在仍属于相等子图。

两端都不在交错树中的边(i,j)A[i]B[j]都没有变化。也就是说,它原来属于(或不属于)相等子图,现在仍属于(或不属于)相等子图。

X端不在交错树中,Y端在交错树中的边(i,j),它的A[i]+B[j]的值有所增大。它原来不属于相等子图,现在仍不属于相等子图。

X端在交错树中,Y端不在交错树中的边(i,j),它的A[i]+B[j]的值有所减小。也就说,它原来不属于相等子图,现在可能进入了相等子图,因而使相等子图得到了扩大。

  现在的问题就是求d值了。为了使A[i]+B[j]>=w[i,j]始终成立,且至少有一条边进入相等子图,d应该等于min{A[i]+B[j]-w[i,j]|Xi在交错树中,Yi不在交错树中}

  以上就是KM算法的基本思路。但是朴素的实现方法,时间复杂度为O(n4)——需要找O(n)次增广路,每次增广最多需要修改O(n)次顶标,每次修改顶标时由于要枚举边来求d值,复杂度为O(n2)。实际上KM算法的复杂度是可以做到O(n3)的。我们给每个Y顶点一个“松弛量”函数slack,每次开始找增广路时初始化为无穷大。在寻找增广路的过程中,检查边(i,j)时,如果它不在相等子图中,则让slack[j]变成原值与A[i]+B[j]-w[i,j]的较小值。这样,在修改顶标时,取所有不在交错树中的Y顶点的slack值中的最小值作为d值即可。但还要注意一点:修改顶标后,要把所有的slack值都减去d

 

 

 

 

这道题还有一个正解:最小费用最大流!

构图如下:

 

 

这个代码北大过了,不知道为啥NBU的很强大,过不了= =!

  

 

下面这个都能过,当作模板

原创粉丝点击