poj 2195 Going Home (km算法)
题目链接:
http://poj.org/problem?id=2195
解题思路:
把man和home都提取出来,然后算出每个man和home的距离算出来,然后建立匹配图,套用km算法的模板,求最小权值匹配,km模板一般是求最大权匹配,求最小的话,一般是取负,当然如果感觉取负逼格太low,也可以用下面的办法,改进模板。
代码:
//写的代码太菜,不懂建立匹配图的时候为什么下表从零开始就会使劲wa,但是改成1就会ac,有看出来的小伙伴们请大声说出来,跪谢!!!!!
//KM算法求完备匹配下的最小权匹配
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std; #define maxn 110
#define INF 0x3f3f3f3f
int map[maxn][maxn]/*匹配图*/;
int used[maxn]/*x与y的匹配值*/;
int s[maxn]/*修改量*/;
int n, m;
int lx[maxn], ly[maxn];/*顶标*/
int visx[maxn], visy[maxn]; struct node
{
int x, y;
void init(int xx, int yy)
{
x = xx;
y = yy;
}
}; int Fas(int x, int y)
{
if (x > y)
return x - y;
return y - x;
}
int find (int x)
{//匈牙利算法,增广路经,扩大相等子图
visx[x] = ;
for (int i=; i<n; i++)
{
if (!visy[i] && lx[x]+ly[i] == map[x][i])
{
visy[i] = ;
if (!used[i] || find(used[i]))
{
used[i] = x;
return ;
}
}
else
//s[i] = min (s[i], lx[x] + ly[i] - map[x][i]);
//最大权匹配
s[i] = min (s[i], map[x][i] - (lx[x] + ly[i]));//更新修改值,保证最小,使求得的结果最优
}
return ;
}
int KM()
{
memset (used, , sizeof(used));
memset (ly, , sizeof(ly));
for (int i=; i<n; i++)//初始化顶标
lx[i] = INF;//lx[i] = 0;最大权匹配 for (int i=; i<n; i++)
for (int j=; j<n; j++)
lx[i] = min(lx[i], map[i][j]); for (int i=; i<n; i++)
{
for (int j=; j<n; j++)
s[j] = INF;
while ()
{
memset (visx, , sizeof(visx));
memset (visy, , sizeof(visy)); if (find(i))
break; int num = INF;
for (int j=; j<n; j++)
if (!visy[j])//
num = min (num, s[j]); for (int j=; j<n; j++)
{
if (visx[j])
lx[j] += num;//lx[j] -= num;最大权匹配
if (visy[j])
ly[j] -= num;//ly[j] += num;最大权匹配
else
s[j] -= num;
}
}
}
int res = ;
for (int i=; i<n; i++)
res += map[used[i]][i];
return res; }
int main ()
{
char str[maxn];
int a, b;
node home[maxn], man[maxn];
while (scanf ("%d %d", &a, &b), a+b)
{
n = m = ;
memset (map, , sizeof(map)); for (int i=; i<a; i++)
{
scanf ("%s", str);
for (int j=; str[j]; j++)
{
if (str[j] == 'H')
home[n++].init(i, j);
if (str[j] == 'm')
man[m++].init(i, j);
}
}
for (int i=; i<n; i++)
for (int j=; j<m; j++)
map[i][j] = Fas(home[i].x , man[j].x) + Fas(home[i].y , man[j].y);
printf ("%d\n", KM());
}
return ;
}
poj 2195 Going Home (km算法)的更多相关文章
- poj 2195 KM算法
题目链接:http://poj.org/problem?id=2195 KM算法模板~ 代码如下: #include "stdio.h" #include "string ...
- 【POJ 2195】 Going Home(KM算法求最小权匹配)
[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- POJ - 2195 Going Home 【KM】
题目链接 http://poj.org/problem?id=2195 题意 在一张N * M 的地图上 有 K 个人 和 K 个房子 地图上每个点都是认为可行走的 求 将每个人都分配到不同的房子 求 ...
- [ACM] POJ 3686 The Windy's (二分图最小权匹配,KM算法,特殊建图)
The Windy's Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4158 Accepted: 1777 Descr ...
- poj 3565 uva 1411 Ants KM算法求最小权
由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...
- (网络流 匹配 KM) Going Home --poj -- 2195
链接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82835#problem/D 有n个人有n栋房子,每栋房子里能进一个人,但每走一格 ...
- poj - 3686 The Windy's (KM算法)
题意:n个订单和m个生产车间,每个订单在不同的车间生产所需要的时间不一样,并且每个订单只能在同一个车间中完成,直到这个车间完成这个订单就可以生产下一个订单.现在需要求完成n个订单的平均时间最少是多少. ...
- KM poj 2195
题意:给出一个地图,地图上有人和房子,问如何分配哪个人去哪个房子,走的路最短? 这道题是个完备匹配的情况下,问怎么才能走的路最少,可以用KM来做. 只不过KM算法是用来求解最大最优值,所以我们得改一下 ...
- poj 2195 二分图带权匹配+最小费用最大流
题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...
随机推荐
- dubbo-admin安装和使用
更新下链接,不知道是不是这个项目合入Apache的缘故,链接都变成了https://github.com/apache/incubator-dubbo/ 按照常理,直接去 https://github ...
- windows下开发PHP扩展dll(无需Cygwin)
windows下开发php扩展网上很多资料都说需要Cygwin,其实完全可以不必安装该东东.没错,是可以在linux下生成骨架后拷到windos下来用,但是,如果没有linux环境呢?什么,装虚拟机? ...
- 去掉小程序textarea上的完成按钮栏
小程序textarea上会自动多一个完成按钮,如下图所示,如果是mpVue,在textarea添加 :show-confirm-bar="false" 即可.
- 字符设备之poll机制
poll机制作用:相当于一个定时器.时间到了还没有资源就唤醒进程. 主要用途就是:进程设置一段时间用来等待资源,假设时间到了资源还没有到来,进程就立马从睡眠状态唤醒不再等待.当然这仅仅是使用于这段时间 ...
- 微信小程序之 Swiper(轮播图)
1.逻辑层 mine.js // pages/mine/mine.js Page({ /** * 页面的初始数据 */ data: { /*轮播图 配置*/ imgUrls: [ 'http://im ...
- 项目实战之玩转div+css制作自己定义形状
项目需求 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/diss ...
- OpenCV图像处理篇之图像平滑
图像平滑算法 图像平滑与图像模糊是同一概念,主要用于图像的去噪.平滑要使用滤波器.为不改变图像的相位信息,一般使用线性滤波器,其统一形式例如以下: %20\Large%20g(i,j)=\sum_{k ...
- hdu1576 mod 运算的逆元
Problem Description 要求(A/B)%9973,但因为A非常大,我们仅仅给出n(n=A%9973)(我们给定的A必能被B整除.且gcd(B,9973) = 1). Input 数 ...
- DLR之 ExpandoObject和DynamicObject的使用演示样例
ExpandoObject :动态的增删一个对象的属性,在低层库(比如ORM)中非常实用.因为ExpandoObject实现了IDictionay<string, object>接口,常见 ...
- [IT学习]转载python 项目 计算器
这个是从网上搜到的Python小项目之计算器(原文地址:http://www.2cto.com/kf/201402/279637.html).但该段代码估计是Python 2 写的. 如果你使用的程序 ...