using namespace std; struct Edge{ int from,to,cap,flow,cost; Edge(int from,int to,int cap,int flow,int cost):from(from),to(to),cap(cap),flow(flow),cost(cost){} }; struct node{ int x,y; }man[maxn],house[maxn]; int m_cnt,h_cnt; int S,T; int x,y; int dis(int x1,int y1,int x2,int y2){ return abs(x1-x2)+abs(y1-y2); } struct MCMF{ int n,m,s,t; vector<Edge>edges; vector<int>G[maxn]; int inq[maxn],d[maxn],p[maxn],a[maxn]; void init(int n){ this->n=n; for(int i=0;i<n;i++) G[i].clear(); edges.clear(); } void AddEdge(int from,int to,int cap,int cost){ edges.push_back(Edge(from,to,cap,0,cost)); edges.push_back(Edge(to,from,0,0,-cost)); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BellmanFord(int s,int t,int &flow,int& cost){ for(int i=0;i<n;i++) d[i]=inf; memset(inq,0,sizeof(inq)); d[s]=0,inq[s]=1,p[s]=0,a[s]=inf; queue<int>Q; Q.push(s); while(!Q.empty()){ int u=Q.front(); Q.pop(); inq[u]=0; for(int i=0;i<G[u].size();i++){ Edge& e=edges[G[u][i]]; if(e.cap>e.flow && d[e.to]>d[u]+e.cost){ d[e.to]=d[u]+e.cost; p[e.to]=G[u][i]; a[e.to]=min(a[u],e.cap-e.flow); if(!inq[e.to]){ Q.push(e.to); inq[e.to]=1; } } } } if(d[t]==inf) return false; flow+=a[t]; cost+=d[t]*a[t]; int u=t; while(u!=s){ edges[p[u]].flow+=a[t]; edges[p[u]^1].flow-=a[t]; u=edges[p[u]].from; } return true; } int Mincost(int s,int t){ int flow=0,cost=0; while(BellmanFord(s,t,flow,cost)); return cost; } }; MCMF g; void creatmap(){ m_cnt=0,h_cnt=0; memset(man,0,sizeof(man)); memset(house,0,sizeof(house)); for(int i=0;i<x;i++){ string st; cin>>st; for(int j=0;j<st.length();j++){ if(st[j]=='H'){ h_cnt++; house[h_cnt].x=i+1; house[h_cnt].y=j+1; } else if(st[j]=='m'){ m_cnt++; man[m_cnt].x=i+1; man[m_cnt].y=j+1; } } } S=0,T=h_cnt+m_cnt+1; g.init(h_cnt+m_cnt+2); for(int i=1;i<=h_cnt;i++) g.AddEdge(S,i,1,0); for(int i=1;i<=m_cnt;i++) g.AddEdge(i+h_cnt,T,1,0); for(int i=1;i<=h_cnt;i++){ for(int j=1;j<=m_cnt;j++){ int d=dis(house[i].x,house[i].y,man[j].x,man[j].y); g.AddEdge(i,j+h_cnt,1,d); } } } int main(){ // freopen("input.txt","r",stdin); ios::sync_with_stdio(false); cin.tie(0); while(cin>>x>>y){ if(x==0 && y==0) break; creatmap(); cout<<g.Mincost(S,T)<<endl; } return 0; }
|