POJ_2195_Going Home
2015-08-28 21:37
477 查看
题意:用'H','m','.'作出矩阵,'H'代表房子,'m'代表人,人一次只能水平或者垂直移动到相邻的点,问所有人一共走的步数的最小值。
分析:明显的求二分图最大权匹配。KM算法求得的是最大权匹配,而题中要求的是最小值,所以要将边的权值以其负值储存。
有一点需要注意:link数组(匹配数组)必须初始化为-1,如果初始化为0,则link[0]=0,则默认第0个人与第0个房子匹配,在执行匈牙利算法是就会出错,找到错误的增广路,第一次提交就错在这。
总结:基本能只用KM算法,熟练度还有待增强。
代码:
分析:明显的求二分图最大权匹配。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 ; Point man ; int n,m; int cnth,cntm; int lx ,ly ,link ,w ; bool S ,T ; char grid ; int dis(Point a,Point b) { return (abs(a.x-b.x)+abs(a.y-b.y)); } void update() { int a=99999999; for(int i=0; i<cnth; i++) if(S[i]) for(int j=0; j<cntm; j++) if(!T[j]) a=min(a,lx[i]+ly[j]-w[i][j]); for(int i=0; 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=0; j<cntm; j++) if(lx[i]+ly[j]-w[i][j]==0&&!T[j]) { T[j]=true; if(link[j]==-1||match(link[j])) { link[j]=i; return true; } } return false; } void KM() { Del(link,-1); ///必须初始化为-1,如果初始化为0,则link[0]=0,则默认第0个人与第0个房子匹配,在执行匈牙利算法是就会出错,找到错误的增广路 for(int i=0; i<cnth; i++) { lx[i]=ly[i]=0; for(int j=0; j<cntm; j++) lx[i]=max(lx[i],w[i][j]); } for(int i=0; i<cnth; i++) for(;;) { Del(S,0); Del(T,0); if(match(i)) break; else update(); } } int main() { while(~scanf("%d%d",&n,&m)&&n!=0) { cntm=cnth=0; for(int i=0; i<n; i++) { scanf("%s",grid); for(int j=0; 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=0; i<cnth; i++) for(int j=0; j<cntm; j++) w[i][j]=-dis(house[i],man[j]); KM(); int ans=0; for(int i=0; i<cntm; i++) ans+=dis(house[link[i]],man[i]); printf("%d\n",ans); } return 0; }
相关文章推荐
- Foundation框架中字符串的查找(rangOfString)
- Goods:注册页面保存User功能发送邮件以及激活功实现
- 华为oj:名字的漂亮度
- HDU 1056.HangOver【水!水!水!】【8月28】
- django 1.8 官方文档翻译: 3-1-4 视图装饰器
- django 1.8 官方文档翻译: 3-2-1 内建的视图
- django 1.8 官方文档翻译: 3-4-3 使用基于类的视图处理表单
- 从Google Map爬数据
- Cross Site Tracing (XST) Attacks(跨站跟踪攻击)练习详细步骤(WebGoat5.4)
- django 1.8 官方文档翻译: 3-4-1 基于类的视图
- 开发游戏测试服管理工具
- mongo的登录认证与角色管理。
- Got minus one from a read call异常
- Django form 实现文件上传
- Django form 实现文件上传
- 自己写的一个LINGO程序,欢迎指教
- mongo和pymongo简单配置和使用
- How Hash Algorithms Work
- 百度地图经纬度转换到腾讯地图/Google 对应的经纬度
- robomongo的使用