#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#define MAXN 210
#define MAXE 30010
#define FOR(i_,a,b) for( int i_ = a; i_ <= b; i_ ++ )
#define INF 0x7ffffff
using namespace std;
struct Node
{
int x;
int y;
} M[MAXN], H[MAXN];
struct EDGE
{
int u, v,next;
int flow, cost, cap ;
}e[MAXE];
int head[MAXN];
int dis_road( int a, int b )
{
return abs(M[a].x-H[b].x)+abs(M[a].y-H[b].y);
}
void add_edge( int u, int v, int cap, int cost, int &num )
{
e[num].u = u;
e[num].v = v;
e[num].cap = cap;
e[num].flow = 0;
e[num].cost = cost;
e[num].next = head[u];
head[u] = num ++;
e[num].u = v;
e[num].v = u;
e[num].flow = 0;
e[num].cap = 0;
e[num].cost = -cost;
e[num].next = head[v];
head[v] = num ++;
}
int get_map( int m, int n )
{
char map[110];
int num = 0, mn = 0, hn = 0;
FOR(i,0,m-1) {
scanf("%s",map);
FOR(j,0,n-1){
if( map[j] =='H' ) H[++hn].x = i, H[hn].y = j;
if( map[j] == 'm' )M[++mn].x = i, M[mn].y = j;
}
}
FOR(i,0,MAXN )head[i] = -1;
int s = 0, t = hn*2+1;
FOR(i,1,mn) {
add_edge( s,i, 1, 0, num );
add_edge( mn+i, t, 1, 0, num );
FOR(j,1,hn) add_edge( i, j+mn, 1, dis_road(i,j), num );
}
return t;
}
int d[MAXN],path[MAXN], c[MAXN], que[MAXN];
bool iq[MAXN];
bool spfa( int s, int t, int n )
{
int front = 0, rear = 0;
FOR(i,0,n ) d[i] = INF, iq[i] = false;
d[s]= 0;
c[s] = INF;
path[s] = s;
iq[s] = true;
que[rear++] = s;
while(rear!=front)
{
int u = que[front++];
if( front == MAXN ) front = 0;
iq[u] = false;
for( int p = head[u]; p!=-1; p = e[p].next )
if( e[p].cap > e[p].flow && d[ e[p].v ] > d[ u ] + e[p].cost )
{
d[ e[p].v ] = d[u] + e[p].cost;
c[ e[p].v ] = min( c[u], e[p].cap - e[p].flow );
path[ e[p].v ] = p;
if( !iq[ e[p].v ] )
{
iq[ e[p].v] = true;
que[rear++] = e[p].v;
if( rear == MAXN ) rear = 0;
}
}
}
if( d[t] == INF ) return false;
else return true;
}
int mincost( int s, int t, int n )
{
int flow = 0, cost = 0;
while( spfa( s, t, n ) )
{
flow += c[t];
cost += c[t]*d[t];
for( int u = t; u!=s; u = e[ path[u] ].u )
{
e[ path[u] ].flow += c[t];
e[ path[u]^1 ].flow -= c[t];
}
}
return cost;
}
int main()
{
//freopen("in.txt","r", stdin );
int m, n;
while( ~scanf("%d%d",&m,&n), m+n )
{
int t = get_map( m, n );
printf("%d\n",mincost(0,t, t+1));
}
return 0;
}
poj 2195
最新推荐文章于 2020-10-13 14:47:51 发布