#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
using namespace std;
#define PF(x) (scanf("%d",&x))
#define PT(x,y) (scanf("%d%d",&x,&y))
#define PR(x) (printf("%d\n",x))
#define PRT(x,y)(printf("%d %d\n",x,y))
#define PB(x)(scanf("%I64d",&x))
#define PRB(x)(printf("%I64d\n",(x)))
#define For(i,n) for(int i=0;i<(n);i++)
typedef __int64 LL;
#define N 205
#define M 105
#define Mod 1000
#define Inf 0x7fffffff
struct P
{
int x,y;
int len(P b)
{
return abs(x-b.x)+abs(y-b.y);
}
void in(int x,int y)
{this->x = x;this->y = y;}
};
P ar[N];
P arr[N];
int n,m;
int tos;
char ma[N][N];
int cost[N][N];
int cap[N][N];
int dist[N];
int recap[N][N];
queue<int> G;
int pre[N];
int vis[N];
int k;
int minx(int a,int b)
{
return a>b?b:a;
}
bool readata()
{
scanf("%d%d",&n,&m);
tos = 1;
k = 1;
if(n==0 && m ==0) return false;
for(int i=0;i<n;i++)
{
scanf("%s",ma[i]);
for(int j=0;j<m;j++)
if(ma[i][j] == 'H') ar[tos++].in(i,j);
else if(ma[i][j] == 'm') arr[k++].in(i,j);
}
return true;
}
void constructmap()
{
memset(cost,0,sizeof(cost));
memset(cap,0,sizeof(cap));
tos--;k--;
for(int i=1;i<=tos;i++)
for(int j=1;j<=k;j++)
cost[i][j+tos] = ar[i].len(arr[j]),
cap[i][j+tos] = 1,cost[j+tos][i] = - cost[i][j+tos];
for(int i=1;i<=tos;i++)
cost[0][i] = 0,cap[0][i] = 1;
for(int i=tos+1;i<=tos+k;i++)
cost[i][tos+k+1] =0,cap[i][tos+k+1]=1;
}
int bfs(int s,int ts)
{
while(!G.empty()) G.pop();
memset(recap,0,sizeof(recap));
int flow = 0;
int money = 0;
for(;;)
{
for(int i=0;i<=tos+k+1;i++) dist[i] = Inf;
dist[s]=0;
memset(vis,0,sizeof(vis));
G.push(s);
while(!G.empty())
{
int t = G.front();G.pop();
vis[t] = 0;
for(int i=0;i<=ts;i++)
if(cap[t][i]>recap[t][i] && dist[i]>dist[t]+cost[t][i])
{
dist[i] = dist[t]+cost[t][i];
pre[i] = t;
if(!vis[i])
{
vis[i] = 1;
G.push(i);
}
}
}
if(dist[ts] == Inf) break;
int mins = Inf;
//for(int t= ts;t!=s;t=pre[t]) mins = minx(cap[pre[t]][t] - recap[pre[t]][t],mins);
for(int t = ts;t!=s;t=pre[t])
{
recap[pre[t]][t] += 1;
recap[t][pre[t]] -= 1;
}
flow += 1;
money += dist[ts];
}
return money;
}
void init()
{
while(readata())
{
constructmap();
PR(bfs(0,tos+k+1));
}
return ;
}
int main()
{
init();
return 0;
}
hdu 1533
最新推荐文章于 2017-02-26 18:04:39 发布