1 /*
2 将 maxn 定位 200 不是超时 就是wa 定位300 32ms 过 纠结。。。。。。。
3
4 题意:一个row*col的矩阵,m表示人,H表示房子,.表示空地,人数和房子数相等,如下图:
5 5 5
6 HH..m
7 .....
8 .....
9 .....
10 mm..H
11 现在要让所有的人都进入不同的房子内,问总共最少走多少步?
12 将 人看作是 源点 房子 看作是 汇点
13
14 思路:最小费用最大流。
15
16 */
17
18 #include<stdio.h>
19 #include<string.h>
20 #define maxn 300
21 #define inf 0x7fffffff
22 #include<cmath>
23 int min(int x,int y)
24 {
25 if(x<y)return x;
26 else return y;
27 }
28 struct node
29 {
30 int x;
31 int y;
32 }h[maxn],man[maxn];
33 int map[maxn][maxn],vis[maxn],cap[maxn][maxn],dis[maxn];
34 int que[maxn],pre[maxn];
35 int num,ans;
36 int SPFA()
37 {
38
39 int i;
40 memset(vis,0,sizeof(vis));
41 for(i=0;i<=num;i++)dis[i]=inf;
42 dis[0]=0;
43 vis[0]=1;
44
45 int head=0,tail=0;
46 que[0]=0;
47 tail++;
48 while(head!=tail)
49 {
50 int k=que[head];
51
52 vis[k]=0;
53 for(i=0;i<=num;i++)
54 {
55 if(cap[k][i]&&dis[i]>dis[k]+map[k][i])
56 {
57 dis[i]=dis[k]+map[k][i];
58 pre[i]=k;
59
60 if(!vis[i])
61 {
62 vis[i]=1;
63 que[tail++]=i;
64 if(tail==maxn)tail=0;
65 }
66 }
67 }
68 head++;
69 if(head==maxn)head=0;
70
71 }
72 if(dis[num]<inf)return 1;//这里要注意 和最大流的不同
73 else
74 return 0;
75 }
76 void end()
77 {
78 int i,sum=inf;
79 for(i=num;i!=0;i=pre[i])
80 {
81 sum=min(sum,cap[pre[i]][i]);
82 }
83 for(i=num;i!=0;i=pre[i])
84 {
85 cap[pre[i]][i]-=sum;
86 cap[i][pre[i]]+=sum;
87 ans+=map[pre[i]][i]*sum;
88 }
89
90 }
91 int main()
92 {
93 int hnum,mnum,n,m,i,j;
94 char c;
95 while(scanf("%d%d",&n,&m)!=EOF)
96 {
97 if(n==0&&m==0)break;
98 hnum=0;
99 mnum=0;
100 getchar();
101 for(i=0;i<n;i++)
102 {
103 for(j=0;j<m;j++)
104 {
105 scanf("%c",&c);
106 if(c=='H')
107 {
108 h[++hnum].x=i;
109 h[hnum].y=j;
110 }
111 if(c=='m')
112 {
113 man[++mnum].x=i;
114 man[mnum].y=j;
115 }
116 }
117 getchar();
118 }
119 memset(cap,0,sizeof(cap));
120 memset(map,0,sizeof(map));
121 for(i=1;i<=mnum;i++)
122 {
123
124 for(j=1;j<=hnum;j++)
125 {
126
127 cap[i][j+mnum]=1;
128 map[i][j+mnum]=fabs(man[i].x-h[j].x)+fabs(man[i].y-h[j].y);
129 map[j+mnum][i]=-map[i][j+mnum];
130 }
131 }
132 num=mnum+hnum+1;
133 for(i=1;i<=mnum;i++)
134 {
135 map[0][i]=map[i][0]=0;
136 cap[0][i]=1;
137
138 }
139 for(i=mnum+1;i<num;i++)
140 {
141 map[i][num]=map[num][i]=0;
142 cap[i][num]=1;
143 }
144 ans=0;
145 while(SPFA())end();
146 printf("%d\n",ans);
147
148
149 }
150 }