题意:小矮人回家,最小的花费
解法:KM模板题
先吐槽一下,多校,呵呵~
在吐槽一下, 这书上的代码貌似都是kuangbin的~囧,那你书上整对啊,书上都不对,哎
/*
----------------------------------
Love is more than a word.
It says so much.
When I see these four letters,
I almost feel your touch.
This is only happened since
I fell in love with you.
Why this word does this,
I haven't got a clue.
To My Goddess
CY
----------------------------------
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#define maxn 300+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define REP(i,a,b) for(i=a;i<=b;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define clehead(a) rep(i,maxn)a[i]=-1
/*
The time of story :
** while(1)
{
once upon a time,
there was a mountain,
on top of which there was a temple,
in which there was an old monk and a little monk.
Old monk was telling stories inside the temple.
What was he talking about?
** }
ÎûÎû
(*^__^*)
*/
#define sci(a) scanf("%d",&a)
#define scd(a) scanf("%lf",&a)
#define pri(a) printf("%d",a)
#define prie(a) printf("%d\n",a)
#define prd(a) printf("%lf",a)
#define prde(a) printf("%lf\n",a)
#define pre printf("\n")
#define LL(x) x<<1
#define RR(x) x<<|1
#define pb push_back
#define mod 90001
#define PI 3.141592657
const ull INF = 1LL << 61;
const int inf = int(1e9)+10;
const double eps=1e-5;
using namespace std;
struct node
{
int x,y;
};
bool cmp(int a,int b){
return a>b;
}
int mat[maxn][maxn],match1[maxn],match2[maxn];
int km(int m,int n)
{
int s[maxn],t[maxn],l1[maxn],l2[maxn],p,q,ret=0,i,j,k;
rep(i,m){
for(l1[i]=-inf,j=0;j<n;j++)l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i];
if(l1[i]==-inf)return -1;
}
for(i=0;i<n;l2[i++]=0);
memset(match1,-1,sizeof(match1));
memset(match2,-1,sizeof(match2));
for(i=0;i<m;i++)
{
memset(t,-1,sizeof(t));
for(s[p=q=0]=i;p<=q&&match1[i]<0;p++)
{
for(k=s[p],j=0;j<n&&match1[i]<0;j++)
{
if(l1[k]+l2[j]==mat[k][j]&&t[j]<0)
{
s[++q]=match2[j],t[j]=k;
if(s[q]<0)
{
for(p=j;p>=0;j=p)
{
match2[j]=k=t[j],p=match1[k],match1[k]=j;
}
}
}
}
}
if(match1[i]<0)
{
for(i--,p=inf,k=0;k<=q;k++)
{
for(j=0;j<n;j++)
{
if(t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p)
{
p=l1[s[k]]+l2[j]-mat[s[k]][j];
}
}
}
for(j=0;j<n;l2[j]+=t[j]<0?0:p,j++);
for(k=0;k<=q;l1[s[k++]]-=p);
}
}
for(i=0;i<m;i++)
{
ret+=mat[i][match1[i]];
}
return ret;
}
int main()
{
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int ip1,ip2;
int n,m;
node l[maxn];
node r[maxn];
while(cin>>n>>m)
{
if(n+m==0)break;
int i,j,k;
char c;
ip1=ip2=0;
rep(i,n){
rep(j,m)
{
cin>>c;
if(c=='m')
{
l[ip1].x=i;
l[ip1++].y=j;
}
else if(c=='H'){
r[ip2].x=i;
r[ip2++].y=j;
}
}
}
rep(i,ip1){
rep(j,ip2)
{
mat[i][j]=-(abs(l[i].x-r[j].x)+abs(l[i].y-r[j].y));
}
}
// cout<<ip1<<":"<<ip2<<endl;
cout<<-km(ip1,ip2)<<endl;
}
return 0;
}