题目链接:

https://vjudge.net/problem/POJ-2195

题目大意:

给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致。man每移动一格需花费$1(即单位费用=单位距离),一间house只能入住一个man。现在要求所有的man都入住house,求最小费用。

思路:

KM算法传送门: 理解篇    运用篇

每个man和house建立带权二分图,曼哈顿距离就是边的值,这里要求最小费用,也就是二分图最小权值匹配,但是KM算法求的是二分图最大权值匹配,所以此处用边的负数求最优匹配,求出来的答案的负数就是最小权匹配。

注意:题目说house最多100,但是没有说明man的范围,所以man应该最多100*100。

应该用house为二分图的X部,因为算法复杂度和X部点数有关,所以用点数少的house为X部

因为存的是负数,在预处理X部的顶标值初始化应该是-INF,不能是0

剩下的就是模板啦

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxx = + ;//house的上限
const int maxy = + ;//man的上限
const int INF = 0x3f3f3f3f;
int cntx, cnty;//X部的点的数目,Y部点的数目
bool visx[maxx], visy[maxy];//是否加入增广路
int wx[maxx], wy[maxy];//顶标值
int cx[maxx], cy[maxy];//匹配的点
int minz;//顶标值和边权最小的差值
int Map[maxx][maxy];//保存边 bool dfs(int u)
{
visx[u] = ;
for(int v = ; v <= cnty; v++)
{
if(!visy[v])//还未加入增广路
{
int t = wx[u] + wy[v] - Map[u][v];
//计算边权和顶标之差,为0表示是相等子图
if(t == )
{
visy[v] = ;
if(cy[v] == - || dfs(cy[v]))//还未匹配或者反向找到增广路
{
cy[v] = u;
cx[u] = v;
//cout<<u<<"v"<<v<<endl;
return ;
}
}
else if(t > )minz = min(minz, t);
}
}
return ;
} int KM()
{
memset(cx, -, sizeof(cx));
memset(cy, -, sizeof(cy));
memset(wx, -INF, sizeof(wx));//注意,这里存的是负边,所以初始化必须是负无穷
memset(wy, , sizeof(wy));
for(int i = ; i <= cntx; i++)//预处理出X部的顶标值
{
for(int j = ; j <= cnty; j++)
{
wx[i] = max(wx[i], Map[i][j]);
//cout<<wx[i]<<endl;
}
}
for(int i = ; i <= cntx; i++)
{
while()
{
minz = INF;
memset(visx, , sizeof(visx));
memset(visy, , sizeof(visy));
if(dfs(i))break; for(int j = ; j <= cntx; j++)
if(visx[j])wx[j] -= minz;
for(int j = ; j <= cnty; j++)
if(visy[j])wy[j] += minz;
}
}
int ans = ;
for(int i = ; i <= cntx; i++)
if(cx[i] != -)ans += Map[i][cx[i]];
return ans;
}
struct node
{
int x, y;
node(){}
node(int x, int y):x(x), y(y){}
};
node house[maxx], man[maxy];
char M[][];
int main()
{
int n, m;
while(cin >> n >> m && (n && m))
{
cntx = cnty = ;
for(int i = ; i < n; i++)//读图
{
cin >> M[i];
for(int j = ; j < m; j++)
{
if(M[i][j] == 'H')house[++cntx] = node(i, j);
else if(M[i][j] == 'm')man[++cnty] = node(i, j);
}
} for(int i = ; i <= cntx; i++)//建图
{
for(int j = ; j <= cnty; j++)
{
Map[i][j] = -abs(house[i].x - man[j].x) - abs(house[i].y - man[j].y);
}
}
cout<<(-KM())<<endl;
}
return ;
}

POJ-2195 Going Home---KM算法求最小权值匹配(存负边)的更多相关文章

  1. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

  2. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  3. hdu1533 Going Home km算法解决最小权完美匹配

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  4. poj 3565 uva 1411 Ants KM算法求最小权

    由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...

  5. poj 2195 Going Home (km算法)

    题目链接: http://poj.org/problem?id=2195 解题思路: 把man和home都提取出来,然后算出每个man和home的距离算出来,然后建立匹配图,套用km算法的模板,求最小 ...

  6. POJ 3565 Ants 【最小权值匹配应用】

    传送门:http://poj.org/problem?id=3565 Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: ...

  7. POJ 2195 Going Home 【二分图最小权值匹配】

    传送门:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  8. 运动员最佳匹配问题 KM算法:带权二分图匹配

    题面: 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势:Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势. ...

  9. HDU 2255 KM算法 二分图最大权值匹配

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

随机推荐

  1. Python中的变量,数据类型

    Python中变量的命名规则:以字母和下划线开头,由字母,数字和下划线组成,区分大小写 Python中同样有加减乘除取余运算,还有一个运算符**,相当与幂运算,当然,幂运算的优先级要高于加减乘除 最后 ...

  2. SCUT - 354 - CC的简单多项式 - 杜教筛

    https://scut.online/p/354 跟多项式一点关系都没有. 注意到其实两个多项式在1处求值,那么就是他们的系数加起来. 列一列发现系数就是n以内两两求gcd的值,还自动把0去掉了. ...

  3. Permutations and Permutations II

    Permutations 问题:给定一个无重复元素的数组,输出其中元素可能的所有排列 示例: 输入:[2,3,4] 输出:[ [2,3,4], [2,4,3], [3,2,4], [3,4,2], [ ...

  4. python之02数据类型学习-作业练习

    题目: 购物车程序 salary = 5000 1. iphone6s 5800 2. mac book 9000 3. coffee 32 4. python book 80 5. bicyle 1 ...

  5. JVM 零散知识

    年轻代大小选择: 响应时间优先的应用: 尽可能设大,直到接近系统的最低响应时间限制.在此种情况下,年轻代收集发生的频率也是最小的.同时,减少到达年老代的对象. 吞吐量优先的应用: 尽可能的设置大,可能 ...

  6. 使用idrac远程管理卡操作安装Centos

    浏览器打开远程管理网卡地址(浏览器建议用IE,本次用的IE11,其他浏览器可能不能用) 1.首先设置虚拟控制台插件类型(推荐该为本地) 点击启动后,可能会弹窗,选择允许 2.添加镜像 创建虚拟介质 连 ...

  7. AT2160 へんなコンパス / Manhattan Compass

    传送门 乍一看像是一个计算几何,然后想到了BFS,但是苦于无奈\(O(n^2)\)不会优化 然后以下参考zjq_shadow大佬的思路 显然发现曼哈顿距离很麻烦,除了暴力枚举貌似没什么很好的办法 考虑 ...

  8. Jmeter_前端RSA加密下的登陆模拟_引用js文件实现(转)

    在一次项目实战中,前端登录使用了RSA加密,使用LoadRunner压测的第一步,就是模拟用户登录,可惜loadRunner11并不能录制前端的加密过程,并且安装的LR是基于C语言版,网络上关于RSA ...

  9. Sharepoint 图片库字段名称(Title)和对应的内部名称(InternalName)

    做项目遇到需要查看列表库的内部名称,因为用的是图片库,所以就列出所有对应关系,以备查看方便:

  10. Luogu P2290 [HNOI2004]树的计数 Prufer序列+组合数

    最近碰了$prufer$ 序列和组合数..于是老师留了一道题:P2624 [HNOI2008]明明的烦恼 qwq要用高精... 于是我们有了弱化版:P2290 [HNOI2004]树的计数(考一样的可 ...