题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2404
模板题:
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll long long
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
#define pii pair<int,int>
#define fi first
#define se second
#define mk(x,y) make_pair(x,y)
const int mod=20100501;
const int maxn=1e2+5;
const int ub=1e6;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
int n,m;
int idx,idx1,idx2,INF;
char s[maxn][maxn];
int vis[maxn<<1],fa[maxn<<1],dis[maxn<<1];
struct node{
int x,y;
}e[maxn<<1];///
int men[maxn],house[maxn];///存储其下标
int cap[maxn<<1][maxn<<1],cost[maxn<<1][maxn<<1];///
int dist(node p,node q){
return abs(p.x-q.x)+abs(p.y-q.y);
}
int spfa(){
mst(vis,0),mst(fa,-1);
queue<int> p;p.push(0);
mst(dis,0xf),INF=dis[0],dis[0]=0;
while(!p.empty()){
int tp=p.front();p.pop();///
///cout<<tp<<endl;
vis[tp]=0;
for(int i=1;i<=idx;i++) if(cap[tp][i]&&dis[i]>dis[tp]+cost[tp][i]){
fa[i]=tp;
dis[i]=dis[tp]+cost[tp][i];
if(vis[i]==0){
vis[i]=1;
p.push(i);
}
}
}
if(dis[idx]<INF) return dis[idx];
return 0;
}
int EK(int x){
int minv=0;
while(spfa()){
for(int i=idx;fa[i]!=-1;i=fa[i]){
cap[fa[i]][i]-=1;
cap[i][fa[i]]+=1;
}
minv+=dis[idx];
}
return minv;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
if(!n&&!m) break;
idx=1,idx1=idx2=0;///下标初始化
mst(cost,0),mst(cap,0);///
rep(i,0,n){
scanf("%s",s[i]);
rep(j,0,m){
if(s[i][j]=='.') continue;
e[idx++]=node{i,j};
if(s[i][j]=='H') house[idx2++]=idx-1;
else men[idx1++]=idx-1;
}
}
rep(i,0,idx1){
cap[0][men[i]]=1;
cost[0][men[i]]=0;
rep(j,0,idx2){
cost[men[i]][house[j]]=dist(e[men[i]],e[house[j]]);
cost[house[j]][men[i]]=-cost[men[i]][house[j]];
cap[men[i]][house[j]]=1;
cap[house[j]][idx]=1;
cost[house[j]][idx]=0;
}
}
printf("%d\n",EK(idx));
}
return 0;
}