HDU_1533 Going Home (optimal matching)
To be honest, at the beginning, this question does not really show that it is the maximum right match under the complete match (of course, this can also be done using network streams. (It should be to add the Source and Sink points. The distance from the source point to each m takes the smallest one from m to all H (the biggest one after the loss of a large number) and the distance from the sink point to each H is similar, and try again if you have time ). I saw it in graph theory 500 in the network flow basics. At first, I couldn't figure out how to stream it! This is the optimal matching for Binary graphs. So I spent a few hours reading the relevant information yesterday and wrote an hdu2255. It was obviously easy to write this question today. We also want to use network streams. It is found that the network stream and the binary match are still related.
- # Include
- # Include
- # Include
- # Include
- # Include
- # Include
- # Define maxn105
- Using namespace std;
-
- Int n, m, numm, numh;
- Int map [MAXN] [MAXN], lx [MAXN], ly [MAXN], vx [MAXN], vy [MAXN], matchy_x [MAXN];
- Char s [MAXN] [MAXN];
- Int abs (int a) {return a <0? -A: ;}
-
- Bool hungary (int u)
- {
- Int I;
- Vx [u] = 1;
- For (I = 0; I {
- If (vy [I] | map [u] [I]! = Lx [u] + ly [I]) continue;
- Vy [I] = 1;
- If (matchy_x [I] =-1 | hungary (matchy_x [I])
- {
- Matchy_x [I] = u;
- Return 1;
- }
- }
- Return 0;
- }
-
- Void EK_match ()
- {
- Int I, j;
- For (I = 0; I {
- Int maxx = 0;
- For (j = 0; j If (map [I] [j]> maxx) maxx = map [I] [j];
- Lx [I] = maxx;
- }
- For (I = 0; I {
- While (1)
- {
- Memset (vx, 0, sizeof (vx ));
- Memset (vy, 0, sizeof (vy ));
- If (hungary (I ))
- Break;
- Else
- {
- Int temp = INT_MAX;
- For (j = 0; j For (int k = 0; k If (! Vy [k] & temp> lx [j] + ly [k]-map [j] [k])
- Temp = lx [j] + ly [k]-map [j] [k];
- For (j = 0; j {
- If (vx [j]) lx [j]-= temp;
- If (vy [j]) ly [j] + = temp;
- }
- }
- }
- }
- }
-
- Int main ()
- {
- Int I, j;
- While (scanf (% d, & n, & m )! = EOF & (n | m ))
- {
- For (I = 0; I Scanf (% s, s [I]);
- Numm = 0;
- For (I = 0; I {
- For (j = 0; j {
- If (s [I] [j] = 'M ')
- {
- Numh = 0;
- For (int k = 0; k {
- For (int l = 0; l {
- If (s [k] [l] = 'H ')
- Map [numm] [numh ++] = 300-(abs (I-k) + abs (j-l ));
- }
- }
- Numm ++;
- }
- }
- }
- Memset (matchy_x,-1, sizeof (matchy_x ));
- EK_match ();
- Int ans = 0;
- For (I = 0; I Ans + = (300-map [matchy_x [I] [I]);
- Printf (% d, ans );
- }
- Return 0;
- }
The following is an optimized slack array:
- # Include
- # Include
- # Include
- # Include
- # Include
- # Include
- # Define maxn105
- Using namespace std;
-
- Int n, m, numm, numh;
- Int map [MAXN] [MAXN], lx [MAXN], ly [MAXN], vx [MAXN], vy [MAXN], matchy_x [MAXN], slack [MAXN];
- Char s [MAXN] [MAXN];
- Int abs (int a) {return a <0? -A: ;}
- Int min (int a, int B) {return
- Bool hungary (int u)
- {
- Int I;
- Vx [u] = 1;
- For (I = 0; I {
- If (vy [I]) continue;
- If (map [u] [I] = lx [u] + ly [I])
- {
- Vy [I] = 1;
- If (matchy_x [I] =-1 | hungary (matchy_x [I])
- {
- Matchy_x [I] = u;
- Return 1;
- }
- }
- Else slack [I] = min (slack [I], lx [u] + ly [I]-map [u] [I]);
- }
- Return 0;
- }
-
- Void EK_match ()
- {
- Int I, j;
- For (I = 0; I {
- Int maxx = 0;
- For (j = 0; j If (map [I] [j]> maxx) maxx = map [I] [j];
- Lx [I] = maxx;
- }
- For (I = 0; I {
- Memset (slack, 127, sizeof (slack ));
- While (1)
- {
- Memset (vx, 0, sizeof (vx ));
- Memset (vy, 0, sizeof (vy ));
- If (hungary (I ))
- Break;
- Else
- {
- Int temp = INT_MAX;
- For (j = 0; j If (temp> slack [j]) temp = slack [j];
- For (j = 0; j {
- If (vx [j]) lx [j]-= temp;
- If (vy [j]) ly [j] + = temp;
- Else slack [j]-= temp;
- }
- }
- }
- }
- }
-
-
- Int main ()
- {
- Int I, j;
- While (scanf (% d, & n, & m )! = EOF & (n | m ))
- {
- For (I = 0; I Scanf (% s, s [I]);
- Numm = 0;
- For (I = 0; I {
- For (j = 0; j {
- If (s [I] [j] = 'M ')
- {
- Numh = 0;
- For (int k = 0; k {
- For (int l = 0; l {
- If (s [k] [l] = 'H ')
- Map [numm] [numh ++] = 300-(abs (I-k) + abs (j-l ));
- }
- }
- Numm ++;
- }
- }
- }
- Memset (matchy_x,-1, sizeof (matchy_x ));
- EK_match ();
- Int ans = 0;
- For (I = 0; I Ans + = (300-map [matchy_x [I] [I]);
- Printf (% d, ans );
- }
- Return 0;
- }