题意:用'H','m','.'作出矩阵,'H'代表房子,'m'代表人,人一次只能水平或者垂直移动到相邻的点,问所有人一共走的步数的最小值。

分析:明显的求二分图最大权匹配。KM算法求得的是最大权匹配,而题中要求的是最小值,所以要将边的权值以其负值储存。

  有一点需要注意:link数组(匹配数组)必须初始化为-1,如果初始化为0,则link[0]=0,则默认第0个人与第0个房子匹配,在执行匈牙利算法是就会出错,找到错误的增广路,第一次提交就错在这。

总结:基本能只用KM算法,熟练度还有待增强。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<stdlib.h>
using namespace std;
#define Del(x,y) memset(x,y,sizeof(x))
#define N 105 struct Point
{
int x,y;
};
Point house[N];
Point man[N]; int n,m;
int cnth,cntm;
int lx[N],ly[N],link[N],w[N][N];
bool S[N],T[N];
char grid[N]; int dis(Point a,Point b)
{
return (abs(a.x-b.x)+abs(a.y-b.y));
}
void update()
{
int a=;
for(int i=; i<cnth; i++)
if(S[i])
for(int j=; j<cntm; j++)
if(!T[j])
a=min(a,lx[i]+ly[j]-w[i][j]);
for(int i=; i<cnth; i++)
{
if(S[i])
lx[i]-=a;
if(T[i])
ly[i]+=a;
}
} bool match(int i)
{
S[i]=true;
for(int j=; j<cntm; j++)
if(lx[i]+ly[j]-w[i][j]==&&!T[j])
{
T[j]=true;
if(link[j]==-||match(link[j]))
{
link[j]=i;
return true;
}
}
return false;
} void KM()
{
Del(link,-); ///必须初始化为-1,如果初始化为0,则link[0]=0,则默认第0个人与第0个房子匹配,在执行匈牙利算法是就会出错,找到错误的增广路
for(int i=; i<cnth; i++)
{
lx[i]=ly[i]=;
for(int j=; j<cntm; j++)
lx[i]=max(lx[i],w[i][j]);
}
for(int i=; i<cnth; i++)
for(;;)
{
Del(S,);
Del(T,);
if(match(i))
break;
else
update();
}
} int main()
{
while(~scanf("%d%d",&n,&m)&&n!=)
{
cntm=cnth=;
for(int i=; i<n; i++)
{
scanf("%s",grid);
for(int j=; j<m; j++)
{
if(grid[j]=='H')
{
house[cnth].x=i;
house[cnth].y=j;
cnth++;
}
if(grid[j]=='m')
{
man[cntm].x=i;
man[cntm].y=j;
cntm++;
}
}
}
for(int i=; i<cnth; i++)
for(int j=; j<cntm; j++)
w[i][j]=-dis(house[i],man[j]);
KM();
int ans=;
for(int i=; i<cntm; i++)
ans+=dis(house[link[i]],man[i]);
printf("%d\n",ans);
}
return ;
}

POJ_2195_Going Home的更多相关文章

随机推荐

  1. Mybatis的配置文件和映射文件具体解释

    一.Mybatis的全局配置文件 1.SqlMapConfig.xml是mybatis的全局配置文件.配置内容例如以下: properties(属性) settings(全局配置參数) typeAli ...

  2. 南阳OJ独木舟上的旅行

     /*独木舟上的旅行 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描写叙述 进行一次独木舟的旅行活动.独木舟能够在港口租到,而且之间没有差别. 一条独木舟最多仅仅能乘坐 ...

  3. Java 实现一个链表

    public class MyList { static class Node {// 节点类 Object data; Node next; public Node(Object data) {// ...

  4. msyql索引详解

    一.mysql查询表索引命令两种形式 1.mysql>SHOW INDEX FROM 'biaoming' 2.mysql>SHOW keys FROM 'biaoming' 运行结果如下 ...

  5. C语言8大经典排序算法(1)

    算法一直是编程的基础,而排序算法是学习算法的开始,排序也是数据处理的重要内容.所谓排序是指将一个无序列整理成按非递减顺序排列的有序序列.排列的方法有很多,根据待排序序列的规模以及对数据的处理的要求,可 ...

  6. Java的Graphics中drawImage与drawLine的坐标区别

    drawImage复制的区域是 dx1 <= x < dx2,dy1 <= y < dy2 drawLine绘制区域是 dx1 <= x <= dx2,dy1 &l ...

  7. YTU 2634: E3 继承了,成员函数却不可访问

    2634: E3 继承了,成员函数却不可访问 时间限制: 1 Sec  内存限制: 128 MB 提交: 521  解决: 435 题目描述 下面的程序中,派生类Derive继承自基类Base,mai ...

  8. 【Dairy】2016.10.17-1 OIer最悲剧的事情

    OIer最悲剧的事情: 看完题,觉得很可做 然后开始码,码了很久                                       一测样例,不过.. 开始肉眼查错..手玩样例.. 过了很久 ...

  9. java异常——重新抛出异常

    有时候希望把刚捕获的异常重新抛出,尤其是在使用Exception捕获所有异常的时候.既然已经得到了对当前异常对象的引用,可以直接把它重新抛出: catch(Exception e){ System.o ...

  10. xubuntu 17.04 和 iphone 6互传文件方法——使用libimobiledevice就可以像u盘一样操作文件了

    I need to preface this by saying I'm also new to Linux, but I've got it working I think. The instruc ...