POJ_2195_Going Home
题意:用'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的更多相关文章
随机推荐
- You don't have permission to access ××× on this server.
之前开发项目一直在linux上用的xampp集成环境,前几天突然想移到window上面去. 開始在window上安装了一个集成环境(名字大概是 Uniform Service),把项目文件已过去, o ...
- ppt五种经典字体组合
在做ppt中常常为使用哪种字体而头疼,如今将ppt的经典字体附上.希望对大家有帮助 五种经典的字体组合 标题字体 正文字体 使用场合 方正综艺简体 微软雅黑 课题汇报.咨询报告.学术研讨等正式场合 方 ...
- Android系统之路(初识MTK) ------ OTA打包ROM安装系统img等到ZIP
在做OTA升级包的时候,我编译了好多次都没过.老是IO异常.刚開始以为是我 make 的错误.后来多次检查 Error 发现是我的配置信息写错了,与驱动project师一起检查源代码, 改动配置信息后 ...
- C中多线程开发
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期.solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,可是在一个进程(proce ...
- ionic/cordova 真机调试
android下简单,连接手机后,直接: myProjectPath>ionic run android ios下比较麻烦点,要先装ios-deploy: sudo npm install - ...
- VS2010打开2012项目(转载)
原文出处:http://www.cnblogs.com/johnsony/p/Version2012To2010.html vs2012 出来了,但是MS还是一如既往的向上兼容. 废话不多说,直接主题 ...
- 【bzoj3124】[Sdoi2013]直径
1.求树的直径: 先随便取一个点,一遍dfs找到离它最远的点l1,再以l1为起点做一遍dfs,找到离l1最远的点l2 那么l1到l2的距离即为直径 2. 求出有多少条边在这棵树的所有直径上: ...
- placeholder 占位符
placeholder 简介 | TensorFlow https://tensorflow.google.cn/programmers_guide/low_level_intro 供给 目前来讲 ...
- bzoj1597 [Usaco2008 Mar]土地购买——斜率优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1597 就是斜率优化水题... 然而WA了十几遍,正负号处理真让人心累... 还是该负就负,别 ...
- jquery plupload上传插件
http://www.jianshu.com/p/047349275cd4 http://www.cnblogs.com/2050/p/3913184.html demo地址: http://chap ...