1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| #include <iostream> #include <cstring> #include <vector> #include <cmath> #include <algorithm> #include <stdio.h> #include <utility>
using namespace std; const int maxn = 110; const int N = 1e4;
int w[maxn][maxn],la[maxn],lb[maxn],match[maxn]; bool va[maxn],vb[maxn]; int n,delta,m,cnt; int house_size,man_size;
struct node { int x,y; }house[N],man[N];
int distance1(node a,node b) { return abs(a.x - b.x) + abs(a.y - b.y); }
int dfs(int x) { va[x] = 1; for (int y=1; y<=house_size; ++y) { if (!vb[y]) if (la[x] + lb[y] - w[x][y] == 0) { vb[y] = 1; if (!match[y] || dfs(match[y])) { match[y] = x; return 1; } } else delta = min(delta,la[x]+lb[y]-w[x][y]); } return 0; }
int KM() { for (int i=1; i<=man_size; ++i) for (int j=1; j<=house_size; ++j) la[i] = max(la[i],w[i][j]); for (int i=1; i<=man_size; ++i) while (1) { memset(va,0,sizeof va); memset(vb,0,sizeof vb); delta = 1 << 30; if (dfs(i)) break; for (int i=1; i<=man_size; ++i) { if (va[i]) la[i] -= delta; if (vb[i]) lb[i] += delta; } } int ans = 0; for (int i=1; i<=house_size; ++i) ans += w[match[i]][i]; return ans; }
void init() { house_size= man_size =0;
delta = 0x3f3f3f3f; memset(w,0,sizeof w); memset(lb,0,sizeof lb); memset(match,0,sizeof match);
for (int i=1; i<=maxn; ++i) la[i] = -0x3f3f3f3f; }
void read() { for (int i=1; i<=cnt; ++i) { for (int j=1; j<=m; ++j) { char ch = getchar(); if (ch == 'H') { house[house_size].x=i; house[house_size++].y=j; } else if (ch == 'm') { man[man_size].x = i; man[man_size++].y=j; } } getchar(); } for (int i=0; i<man_size; ++i) for (int j=0; j<house_size; ++j) w[i+1][j+1] = -distance1(man[i],house[j]); }
int main() { freopen("1.in","r",stdin); while (scanf("%d %d\n",&cnt,&m) && cnt && m) { init(); read(); cout << -KM() << endl; } return 0; }
|