用二分图模型解决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

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前,许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流,但其费用昂贵。鉴于此,众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台,但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境下,商家之间的合作网络逐渐成为一种有效的解决方案,通过资源和客户基础的共享,实现共同的利益增长。 以最近在上海兴起的一个跨行业合作平台为例,该平台融合了环保消费积分系统,在短

Retrieval-based-Voice-Conversion-WebUI模型构建指南

一、模型介绍 Retrieval-based-Voice-Conversion-WebUI(简称 RVC)模型是一个基于 VITS(Variational Inference with adversarial learning for end-to-end Text-to-Speech)的简单易用的语音转换框架。 具有以下特点 简单易用:RVC 模型通过简单易用的网页界面,使得用户无需深入了

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int