题目链接:https://cn.vjudge.net/contest/242366#problem/L

大体意思就是:h代表旅馆,m代表人,人每走动一个需要一个金币,行动只有两个方向,水平或者竖直。问你最终让所有人都能到达旅馆并且花的总费用最少。

具体思路:一开始我是按照km的初级使用进行敲的,结果发现第二组样例过不了,然后km也打的没问题,看了网上的代码,才发现自己的思路错了。这个题的目的是让你花费最小,而km的初级使用是让总费用最低,如果按照一开始的打的话,就南辕北辙了。

但是,花费最小的话,只需要存值的时候把原来的任意两个人和旅馆之间距离赋为负值就可以了。

具体原因:本来km求的是最大值,如果给他加上一个负号,求的也是最大值,相应的变为原来的最小值了(很巧妙)

AC代码:

#include<bits/stdc++.h>
using namespace std;
# define maxn 100+10
# define inf 0x3f3f3f3f
int n,m;
char a[maxn][maxn];
int dis[maxn][maxn];
int nx[maxn*maxn],ny[maxn*maxn];
int visx[maxn*maxn],visy[maxn*maxn];
int slack[maxn*maxn];
int net[maxn*maxn];
int t1,t2;
struct node
{
int x,y;
node() {}
node (int xx,int yy)
{
x=xx;
y=yy;
}
} Pro[maxn*maxn],Hou[maxn*maxn];
void init1()
{
for(int i=1; i<=t1; i++)
{
nx[i]=-inf;
}
memset(ny,0,sizeof(ny));
memset(dis,0,sizeof(dis));
memset(net,0,sizeof(net));
}
void init2()
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
}
bool Find(int t)
{
visx[t]=1;
for(int i=1; i<=t1; i++)
{
int temp=nx[t]+ny[i]-dis[t][i];
if(temp==0)
{
if(visy[i]==0)
{
visy[i]=1;
if(net[i]==0||Find(net[i]))
{
net[i]=t;
return true;
}
}
}
else slack[i]=min(temp,slack[i]);
}
return false;
}
int km()
{
for(int i=1; i<=t1; i++)
{
memset(slack,inf,sizeof(slack));
while(1)
{
init2();
if(Find(i))break;
int minn=inf;
for(int i=1; i<=t1; i++)
{
if(!visy[i])
{
minn=min(minn,slack[i]);
}
}
for(int i=1; i<=t1; i++)
{
if(visx[i])
{
nx[i]-=minn;
}
}
for(int i=1; i<=t2; i++)
{
if(visy[i])
{
ny[i]+=minn;
}
}
}
}
int sum=0;
for(int i=1; i<=t1; i++)
{
if(net[i])
{
sum+=dis[net[i]][i];
}
}
return sum;
} int main()
{
while(cin>>n>>m&&(n+m))
{
init1();
t1=0,t2=0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
cin>>a[i][j];
if(a[i][j]=='m')
{
Pro[++t1].x=i;
Pro[t1].y=j;
}
else if(a[i][j]=='H')
{
Hou[++t2].x=i;
Hou[t2].y=j;
}
}
}
for(int i=1; i<=t1; i++)
{
for(int j=1; j<=t2; j++)
{
dis[i][j]=-(abs(Pro[i].x-Hou[j].x)+abs(Pro[i].y-Hou[j].y));
nx[i]=max(nx[i],dis[i][j]);
}
}
int t=km();
cout<<-t<<endl;
}
return 0;
}

最小费用流(km的另一种使用思路)的更多相关文章

  1. 数据权限设计——基于EntityFramework的数据权限设计方案:一种设计思路

    前言:“我们有一个订单列表,希望能够根据当前登陆的不同用户看到不同类型的订单数据”.“我们希望不同的用户能看到不同时间段的扫描报表数据”.“我们系统需要不同用户查看不同的生产报表列”.诸如此类,最近经 ...

  2. SAP MM 无价值物料管理的一种实现思路

    SAP MM 无价值物料管理的一种实现思路 笔者所在的项目,客户工厂处于先期试生产阶段,尚未开始大规模的商业化生产,但是这并不影响客户集团总部的SAP项目实施.笔者于7月初加入该工厂的第2期SAP项目 ...

  3. Java源码阅读的真实体会(一种学习思路)

    Java源码阅读的真实体会(一种学习思路) 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈 ...

  4. ios - UINavigationBar添加背景图片的几种简单思路

    UITabBarController下面常常需要为多个ViewController设置导航栏样式,总结了一下遇到过的为UINavigationBar添加背景图片的几种简单思路 以设置背景图片为例: 第 ...

  5. Java源码阅读的真实体会(一种学习思路)【转】

    Java源码阅读的真实体会(一种学习思路)   刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+ ...

  6. neo4j - 查询效率的几种优化思路

    最近在公司实习做的就是优化neo4j图形数据库查询效率的事,公司提供的是一个在Linux上搭建且拥有几亿个节点的数据库.开始一段时间主要是熟悉该数据库的一些基本操作,直到上周才正式开始步入了优化数据库 ...

  7. WebGIS中快速整合管理多源矢量服务以及服务权限控制的一种设计思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在真实项目中,往往GIS服务数据源被其他多个信息中心或者第三方 ...

  8. Java-生成指定长度验证码的一种简单思路

     前言:以前做过的一个项目,刚开的时候始验证码是在前端生成前端验证的,后来觉得不靠谱,另外就是找回密码的功能也需要发送邮件和短信的验证码,所以,验证码就必须在后端生成并且保存到应用会话中才行了!所以, ...

  9. Top K问题的两种解决思路

    Top K问题在数据分析中非常普遍的一个问题(在面试中也经常被问到),比如: 从20亿个数字的文本中,找出最大的前100个. 解决Top K问题有两种思路, 最直观:小顶堆(大顶堆 -> 最小1 ...

随机推荐

  1. codeforces625C

    K-special Tables CodeForces - 625C 人们经常做一些疯狂的事来凸显自己.有的人跳舞,有的人撩妹,有的人立志成为顶级程序猿(例如某peng),还有的人喜欢收集有趣的数学对 ...

  2. Java生成多数值二元运算结果集

    看之前大学写过的24点程序中用到的核心计算算法——计算四个值能否计算出24,当时用的c++写的,现用Java重写一遍 程序实现了多个数值(可重复),每个数值只能运算一次,二元运算的条件下获得所有结果集 ...

  3. hdu 3949 XOR (线性基)

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=3949 题意: 给出n个数,从中任意取几个数字异或,求第k小的异或和 思路: 线性基求第k小异或和,因为题 ...

  4. Python Matplot中文显示完美解决方案

    原因与现象 Matplot是一个功能强大的Python图表绘制库,很遗憾目前版本自带的字体库中并不支持中文字体.所以如果在绘制内容中需要显示中文,那么就会显示为方格字符. 解决办法 有一个较为完美的解 ...

  5. 自学Linux Shell2.2-GHOME Terminal仿真器

    点击返回 自学Linux命令行与Shell脚本之路 2.2-GHOME Terminal仿真器 GNOME Terminal是GNOME桌面环境的默认终端仿真器.很多发行版,如RHEL.Fedora和 ...

  6. 【BZOJ2000】[HNOI2000]取石头游戏(贪心,博弈论)

    [BZOJ2000][HNOI2000]取石头游戏(贪心,博弈论) 题面 BZOJ 洛谷 题解 这题好神仙啊,窝不会QaQ. 假装一下只有三个元素\(a_{i-1},a_i,a_{i+1}\),并且满 ...

  7. luogu3320 寻宝游戏 (dfs序+倍增lca+set)

    一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的 所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt) 删掉一个点同理 这个可以用se ...

  8. matplotlib imshow

    简单用法: imshow()函数格式为: matplotlib.pyplot.imshow(X, cmap=None) X: 要绘制的图像或数组. cmap: 颜色图谱(colormap), 默认绘制 ...

  9. linux已开机时间 系统信息

    linux 查看系统运行时间 (从开机当现在的开机时间) 1.uptime命令输出:16:11:40 up 59 days, 4:21, 2 users, load average: 0.00, 0. ...

  10. 洛谷P3195 玩具装箱TOY

    题目大意: 有n个数,要将他们分成若干段,每一段的cost定义为: cost=r-l+ΣCk (k∈[r,l]) 该段的最终花费是:(cost-L)^2; 给出L,n,C(1~n),总共的最小花费. ...