更新时间:2022-08-22 09:51:08
1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 #include<cstdio> 5 #include<algorithm> 6 #define INF 0x3f3f3f3f 7 #define N 1000005 8 using namespace std; 9 10 int cntH, cntM; 11 12 struct node{ 13 int x, y; 14 }; 15 16 struct EDGE{ 17 int u, v, cap, cost, nt; 18 }; 19 EDGE edge[N]; 20 21 queue<int>q; 22 node man[105], house[105]; 23 int first[205]; 24 int dist[205]; 25 int pre[205], flow[205], vis[205]; 26 int cnt, t; 27 int minCost; 28 int n, m; 29 30 void addEdge(int u, int v, int cap, int cost){ 31 edge[cnt].u=u; 32 edge[cnt].v=v; 33 edge[cnt].cap=cap; 34 edge[cnt].nt=first[u]; 35 edge[cnt].cost=cost; 36 first[u]=cnt++; 37 38 edge[cnt].u=v; 39 edge[cnt].v=u; 40 edge[cnt].cap=0; 41 edge[cnt].nt=first[v]; 42 edge[cnt].cost=-cost; 43 first[v]=cnt++; 44 } 45 46 void buildMap(){ 47 memset(first, -1, sizeof(first)); 48 t=cntH+cntM+1; 49 for(int i=1; i<=cntM; ++i) 50 for(int j=1; j<=cntH; ++j) 51 addEdge(i, cntM+j, 1, abs(man[i].x-house[j].x) + abs(man[i].y-house[j].y)); 52 for(int i=1; i<=cntM; ++i) 53 addEdge(0, i, 1, 0); 54 for(int i=1; i<=cntH; ++i) 55 addEdge(cntM+i, t, 1, 0); 56 } 57 58 bool MCMF(){ 59 memset(dist, 0x3f, sizeof(dist)); 60 memset(vis, 0, sizeof(vis)); 61 q.push(0); 62 flow[0]=INF; 63 dist[0]=0; 64 vis[0]=1; 65 while(!q.empty()){ 66 int u=q.front(); q.pop(); 67 vis[u]=0; 68 for(int e=first[u]; ~e; e=edge[e].nt){ 69 int v=edge[e].v, cap=edge[e].cap, cost=edge[e].cost; 70 if(cap>0 && dist[v]>dist[u]+cost){ 71 dist[v]=dist[u]+cost; 72 flow[v]=min(flow[u], cap); 73 pre[v]=e; 74 if(!vis[v]){ 75 vis[v]=1; 76 q.push(v); 77 } 78 } 79 } 80 } 81 if(dist[t]==INF) return false; 82 minCost+=dist[t]; 83 int x=t; 84 while(x!=0){ 85 edge[pre[x]].cap-=flow[t]; 86 edge[pre[x]^1].cap+=flow[t]; 87 x=edge[pre[x]].u; 88 } 89 return true; 90 } 91 92 int main(){ 93 while(scanf("%d%d", &n, &m) && (n||m)){ 94 cnt=cntH=cntM=0; 95 for(int i=1; i<=n; ++i){ 96 getchar(); 97 for(int j=1; j<=m; ++j){ 98 char ch; 99 scanf("%c", &ch); 100 if(ch=='m'){ 101 man[++cntM].x=i; 102 man[cntM].y=j; 103 } 104 else if(ch=='H'){ 105 house[++cntH].x=i; 106 house[cntH].y=j; 107 } 108 } 109 } 110 buildMap(); 111 minCost=0; 112 while(MCMF()); 113 printf("%d\n", minCost); 114 } 115 return 0; 116 }