Creating a graph is simple.
BFS preprocessing map, distance is charged
Source point to all M build edge, traffic 1 cost 0
M to all h edge construction, traffic 1 fee is a distance
H: Build borders at all settlement points. Traffic 1 is free of charge.
# Include <cstdio> # include <queue> # include <algorithm> # include <cstring> using namespace STD; # define maxn 10005 # define maxm 1000000 # define INF 0x3f3f3f3 # define GETID (x, y) x * m + yint DX [] = }; int dy [] = {0, 0,-1, 1}; struct node {int U, V, F, C, next;} e [maxm]; int n, m, head [maxn], pre [maxn], DIST [maxn], vis [maxn], ans; bool use [105] [105]; int en, S, T, maxflow, mincost; // s source point, t sink point void add (int u, int V, int C, int f) // Add edge {e [En]. U = u; E [En]. V = V; E [En]. C = C; E [En]. F = f; E [En]. next = head [u]; head [u] = EN ++; E [En]. U = V; E [En]. V = u; E [En]. C =-C; E [En]. f = 0; E [En]. next = head [v]; head [v] = EN ++;} int spfa () {int I, U, V; for (I = 0; I <= T; I ++) Pre [I] =-1, vis [I] = 0, DIST [I] = inf; Dist [s] = 0; vis [s] = 1; queue <int> q; q. push (s); While (! Q. Empty () {u = Q. Front (); q. Pop (); for (I = head [u]; I! =-1; I = E [I]. next) {v = E [I]. v; If (E [I]. f> 0 & Dist [u] + E [I]. c <Dist [v]) {Dist [v] = DIST [u] + E [I]. c; Pre [v] = I; If (! Vis [v]) {vis [v] = 1; q. push (v) ;}} vis [u] = 0;} If (Dist [T] = inf) return 0; return 1;} void add () {int V; int maxf = inf; For (V = pre [T]; ~ V; V = pre [E [v]. u]) maxf = min (maxf, E [v]. f); For (V = pre [T]; ~ V; V = pre [E [v]. u]) {e [v]. f-= maxf; E [V ^ 1]. F + = maxf; mincost + = E [v]. c;} maxflow + = maxf;} struct pp {int X, Y, DIS; pp (int A, int B) {x = A; y = B; dis = 0 ;}; struct orz {int ID; int W; orz (int A, int B) {id = A; W = B ;}}; vector <orz> GG [10005]; void Init () {maxflow = 0; mincost = 0; en = 0; S = N * m; t = n * m + 1; memset (Head,-1, sizeof (head); For (INT I = 0; I <t; I ++) Gg [I]. clear ();} Char MP [105] [105]; bool isok (int x, int y) {return x> = 0 & x <n & Y> = 0 & Y <M &&! Use [x] [Y];} void BFS (PP t) {pp save = T; queue <PP> q; q. push (t); memset (use, 0, sizeof (use); While (! Q. empty () {pp F = Q. front (); q. pop (); For (int d = 0; D <4; D ++) {T. X = F. X + dx [d]; T. y = f. Y + dy [d]; T. dis = f. DIS + 1; if (isok (T. x, t. y) {use [T. x] [T. y] = 1; q. push (t); If (MP [T. x] [T. y] = 'H') {Gg [GETID (save. x, save. y)]. push_back (orz (GETID (T. x, t. y), T. dis) ;}}}} int main () {While (scanf ("% d", & N, & M )! = EOF) {If (n = 0 & M = 0) break; Init (); vector <PP> V; For (INT I = 0; I <N; I ++) {scanf ("% s", MP [I]); For (Int J = 0; j <m; j ++) {If (MP [I] [J] = 'M') {v. push_back (PP (I, j); add (S, GETID (I, j), 0, 1 );} else if (MP [I] [J] = 'H') {Add (GETID (I, j), T, 0, 1 );}}} for (INT I = 0; I <v. size (); I ++) {BFS (V [I]); int m_id = GETID (V [I]. x, V [I]. y); For (Int J = 0; j <Gg [m_id]. size (); j ++) {int h_id = Gg [m_id] [J]. ID; int Dis = Gg [m_id] [J]. w; add (m_id, h_id, DIS, INF) ;}} while (spfa () add (); printf ("% d \ n", mincost );} return 0 ;}