Going HomeTime
limit:10000/5000 MS (java/others) Memory limit:65536/32768 K (java/others)
Total submission (s): 3452 Accepted Submission (s): 1771
Problem Descriptionon A grid map There is n little men and N houses. In each unit time, every little mans can move one unit step, either horizontally, or vertically, to a adjacent point. For each little mans, you need to pay a $ fee for every step he moves, until he enters a house. The task is complicated with the restriction, each house can accommodate only one little man.
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n Diffe Rent houses. The input is a map of the scenario, a '. ' means an empty space, an ' H ' represents a house on that point, and am ' m ' indica TES There is a little man on this point.
You can think of all the the grid map as a quite large square, so it can hold n little men at the same time; Also, it is the okay if a little man steps on a grid with a house without entering this house.
Inputthere is one or more test cases in the input. Each case starts with a line giving-integers n and m, where N is the number of rows of the map, and M are the number of Columns. The rest of the input would be N lines describing the map. Assume both N and M are between 2 and inclusive. There would be the same number of ' H ' s and ' M's on the map; And there'll is at the most houses. Input would terminate with 0 0 for N and M.
Outputfor each test case, output one line with the single integer, which are the minimum amount, in dollars, your need to PA Y.
Sample Input
2 2.mh.5 5HH.. m...............mm. H7 8...H ..... H....... H....mmmhmmmm ... H....... H....... H.... 0 0
Sample Output
21028
Test instructions
A n*m map has the same number of characters H and character m,m represents a person, H stands for a house. The cost of people to the House is their Manhattan distance in the picture, asking you the minimum fee for getting everyone back to the House (a house can only hold one person).
Solving:
The first minimum cost flow problem, did not dare to write puzzles, chose a naked question to a, feeling Robin God template, thanks to the analysis of small B.
Because it is a naked problem, the idea is still relatively good thinking, simply say a few ideas:
(1) Establish super Source point outset, super meeting point inset.
(2) The source point to each person to build the edge, the capacity of 1, the cost is 0.
(3) The House to the meeting point building edge, capacity of 1, the cost is 0.
(4) Each person and house built side, capacity of 1, cost for Manhattan distance.
From outset to inset run the minimum cost maximum flow on the line.
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define INF 0x3f3f3f3f#define maxn 220#define maxm 88000using namespace std;int N, m;int outset;//super source point int inset;//Super sink struct Node { int u, V, cap, flow, cost, next;}; Node Edge[maxm];int HEAD[MAXN], Cnt;int per[maxn];//record the edge of point I on the augmented path number int DIST[MAXN], vis[maxn];void init () {cnt = 0; Memset (Head,-1, sizeof (head));} void Add (int u, int v, int w, int c) {edge[cnt] = {u, V, W, 0, C, Head[u]}; Head[u] = cnt++; EDGE[CNT] = {V, u, 0, 0,-C, Head[v]}; HEAD[V] = cnt++;} int dir (int x1, int y1, int x2, int y2) {return abs (X1-X2) + ABS (Y1-Y2);} struct node{int x, y;}; NODE MAPH[MAXN], mapm[maxn];int ans_h, Ans_m;void Getmap () {char str[120][120]; Ans_h = ans_m = 0; for (int i = 0; i < n; ++i) {scanf ("%s", Str[i]); for (int j = 0; j < m; ++j) {if (str[i][j] = = ' m ') {ans_m++; mapm[ans_m].x = i; MaPm[ans_m].y = j; } if (str[i][j] = = ' H ') {ans_h++; maph[ans_h].x = i; Maph[ans_h].y = j; }}} int t = ans_h;//number outset = 0;//Source point inset = T * 2 + 1;//sink for (int i = 1; I <= t; ++i) { Add (outset, I, 1, 0); Add (i + t, inset, 1, 0); for (int j = 1; j <= T; ++j) {int d = dir (maph[i].x, Maph[i].y, mapm[j].x, MAPM[J].Y); Add (I, J + T, 1, D); }}//look for the least expensive path//Run once SPFA find the least cost path for st--ed and each edge of the path cannot be full//if there is a description can continue to augment, but not bool SPFA (int st, int ed) {Queue<int>q ; memset (Dist, INF, sizeof (Dist)); memset (Vis, 0, sizeof (VIS)); Memset (per,-1, sizeof (per)); DIST[ST] = 0; VIS[ST] = 1; Q.push (ST); while (!q.empty ()) {int u = q.front (); Q.pop (); Vis[u] = 0; for (int i = head[u]; i =-1; i = Edge[i].next) {node E = Edge[i]; if (DIST[E.V] > Dist[u] + e.cost && e.cap >E.flow) {//can be relaxed and not full stream dist[e.v] = Dist[u] + e.cost; PER[E.V] = i;//record the number of edges that reach this point if (!vis[e.v]) {VIS[E.V] = 1; Q.push (E.V); }}}} ' return per[ed]! =-1;} void MCMF (int st, int ed, int &cost, int &flow) {flow = 0;//Total traffic cost = 0;//Total charge while (SPFA (St, ed)) {//each search The least expensive path is int mins = INF; Find the minimum augmented stream for (int i = per[ed]; i =-1; i = per[edge[i ^ 1].v]) {mins = min (mins, EDG) by the least-cost path of the reverse arc at the source point to the meeting point E[i].cap-edge[i].flow); }//augmented for (int i = per[ed]; i =-1; i = per[edge[i ^ 1].v]) {edge[i].flow + = mins; edge[i ^ 1].flow-= mins; Cost + = Edge[i].cost * mins;//The cost of the augmented stream} Flow + = mins//Total flow accumulation}}int main () {while (scanf ("%d%d", &n, &m), n | | m) {init (); Getmap (); int cost, flow;//min. max Flow MCMF (outset,inset, costing, flow); printf ("%d\n", cost); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 1533--going Home "minimum fee max flow && template"