用二分图模型解决poj 2195

2024-05-27 13:58
文章标签 模型 二分 解决 poj 2195

本文主要是介绍用二分图模型解决poj 2195,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       之前这道题用了费用流来解决,这次用了二分图最佳匹配来解决。

       不过,用二分图最佳匹配解决这道题时,要注意题目要求花费最小,所以是求权值之和最小的最佳匹配。要用一个大数减去原有权值作为新的权值,最后输出答案时,要注意还原真正的权值。

       通过这道题,也可以发现费用流与二分图最佳匹配之间有所关联,而且就这道题来看,二分图的代码量会小于费用流的代码量,所以尽可能采用二分图模型来解决问题可能会简单些。

代码(C++):

#include <cstdlib>
#include <iostream>
#include <cmath>#define MAX 150
#define INF (1<<30)
using namespace std;//#define LOCALtypedef pair<int,int> pii;
pii array_h[MAX],array_m[MAX];int w[MAX][MAX],lx[MAX],ly[MAX],cy[MAX],vx[MAX],vy[MAX];bool match(int u,int n)
{int i;vx[u]=true;for(i=0;i<n;i++){if(lx[u]+ly[i]==w[u][i]&&!vy[i]){vy[i]=true;                            if(cy[i]==-1||match(cy[i],n)){cy[i]=u;return true;                       }                            }            } return false;
}void update(int n)
{int i,j,d;d=INF;for(i=0;i<n;i++) if(vx[i]){for(j=0;j<n;j++) if(!vy[j]){d=min(d,lx[i]+ly[j]-w[i][j]);                     }             } for(i=0;i<n;i++){if(vx[i]) lx[i]-=d;if(vy[i]) ly[i]+=d;            }
}int km(int n)
{int i,j,ans;for(i=0;i<n;i++){lx[i]=-INF;ly[i]=0;cy[i]=-1;for(j=0;j<n;j++) lx[i]=max(lx[i],w[i][j]);           }for(i=0;i<n;i++){while(1){memset(vx,false,sizeof(vx));memset(vy,false,sizeof(vy));if(match(i,n)) break;else update(n);    }            }ans=0;for(i=0;i<n;i++) ans+=w[cy[i]][i];return ans;
}int main(int argc, char *argv[])
{
#ifdef LOCAL freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);
#endifint n,m,a,b,i,j,fee,max;char ch;while(scanf("%d %d",&n,&m)&&n+m!=0){a=b=0;            for(i=0;i<n;i++){getchar();            for(j=0;j<m;j++){scanf("%c",&ch);if(ch=='H') array_h[a++]=make_pair(i,j);else if(ch=='m') array_m[b++]=make_pair(i,j);        }            }max=n+m;for(i=0;i<b;i++){for(j=0;j<a;j++){fee=abs(array_m[i].first-array_h[j].first)+abs(array_m[i].second-array_h[j].second);     w[i][j]=max-fee;       }            } printf("%d\n",max*a-km(a));           }system("PAUSE");return EXIT_SUCCESS;
}

题目( http://poj.org/problem?id=2195):

Going Home
Time Limit: 1000MS Memory Limit: 65536K
   

Description

On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need to pay a $1 travel fee for every step he moves, until he enters a house. The task is complicated with the restriction that each house can accommodate only one little man. 

Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point. 

You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.


Input

There are one or more test cases in the input. Each case starts with a line giving two integers N and M, where N is the number of rows of the map, and M is the number of columns. The rest of the input will be N lines describing the map. You may assume both N and M are between 2 and 100, inclusive. There will be the same number of 'H's and 'm's on the map; and there will be at most 100 houses. Input will terminate with 0 0 for N and M.


Output

For each test case, output one line with the single integer, which is the minimum amount, in dollars, you need to pay.


Sample Input

2 2
.m
H.
5 5
HH..m
.....
.....
.....
mm..H
7 8
...H....
...H....
...H....
mmmHmmmm
...H....
...H....
...H....
0 0


Sample Output

2
10
28

这篇关于用二分图模型解决poj 2195的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1007672

相关文章

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

解决docker目录内存不足扩容处理方案

《解决docker目录内存不足扩容处理方案》文章介绍了Docker存储目录迁移方法:因系统盘空间不足,需将Docker数据迁移到更大磁盘(如/home/docker),通过修改daemon.json配... 目录1、查看服务器所有磁盘的使用情况2、查看docker镜像和容器存储目录的空间大小3、停止dock

idea npm install很慢问题及解决(nodejs)

《ideanpminstall很慢问题及解决(nodejs)》npm安装速度慢可通过配置国内镜像源(如淘宝)、清理缓存及切换工具解决,建议设置全局镜像(npmconfigsetregistryht... 目录idea npm install很慢(nodejs)配置国内镜像源清理缓存总结idea npm in

idea突然报错Malformed \uxxxx encoding问题及解决

《idea突然报错Malformeduxxxxencoding问题及解决》Maven项目在切换Git分支时报错,提示project元素为描述符根元素,解决方法:删除Maven仓库中的resolv... 目www.chinasem.cn录问题解决方式总结问题idea 上的 maven China编程项目突然报错,是

在Ubuntu上打不开GitHub的完整解决方法

《在Ubuntu上打不开GitHub的完整解决方法》当你满心欢喜打开Ubuntu准备推送代码时,突然发现终端里的gitpush卡成狗,浏览器里的GitHub页面直接变成Whoathere!警告页面... 目录一、那些年我们遇到的"红色惊叹号"二、三大症状快速诊断症状1:浏览器直接无法访问症状2:终端操作异常

mybatis直接执行完整sql及踩坑解决

《mybatis直接执行完整sql及踩坑解决》MyBatis可通过select标签执行动态SQL,DQL用ListLinkedHashMap接收结果,DML用int处理,注意防御SQL注入,优先使用#... 目录myBATiFBNZQs直接执行完整sql及踩坑select语句采用count、insert、u

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

Java中字符编码问题的解决方法详解

《Java中字符编码问题的解决方法详解》在日常Java开发中,字符编码问题是一个非常常见却又特别容易踩坑的地方,这篇文章就带你一步一步看清楚字符编码的来龙去脉,并结合可运行的代码,看看如何在Java项... 目录前言背景:为什么会出现编码问题常见场景分析控制台输出乱码文件读写乱码数据库存取乱码解决方案统一使