ZOJ--1654 -- Place the Robots [maximum bipartite matching], robots

Source: Internet
Author: User

ZOJ--1654 -- Place the Robots [maximum bipartite matching], robots

Link:Http://acm.zju.edu.cn/onlinejudge/showProblem.do? ProblemId = 654

Question:Robert is a famous engineer. One day, his boss assigned him a task. The background of the task is: Given a map of m × n size, the map consists of squares, there are three kinds of squares in the map-walls, lawns and open spaces, his boss hopes to put as many robots as possible in the map. Each robot is equipped with a laser gun that can simultaneously shot in four directions (Up, down, left, right. The robot remains in the initial square, cannot move, and then keeps shooting in four directions. A laser shot by a laser gun can penetrate the lawn, but cannot penetrate the walls. Robots can only be placed in open spaces. Of course, the boss does not want robots to attack each other. That is to say, two robots cannot be placed in the same row (horizontal or vertical) unless there is a wall between them. Given a map, your program needs to output the maximum number of robots that can be placed in the map.


Ideas:There is no good idea. The idea in graph theory is good. Stick it directly.

The map 7.23 (a) and (B) described by the two test data in the sample input are shown. In figure (a), up to four robots can be placed. One placement scheme is in (0, 0), (2, 1), (2, 3) and (3, 4) four locations (row and column position numbers start from 0) Place the robot. In figure (B), up to three robots can be placed. One placement scheme is in (0, 0), (2, 1), and (2, 3) place robots in three locations.
In the prototype of the problem, information about lawns and walls is not the concern of this question. This question is only about the relationship between open spaces and open spaces. Therefore, we naturally think of the following simple model: using an open space as the vertex and connecting edges between conflicting open spaces.


In this way, all the spaces in the map shown in Figure 7.23 (a) are marked with numbers, as shown in Figure 7.24 (; connect all conflicting open spaces with edges to obtain the graph (B ). As a result, the problem is transformed into the biggest Independent Set Problem of the graph: finding the largest vertex set, all vertices in the set are not connected (that is, they do not conflict with each other ). However, the largest vertex Independent Set Problem is an NP problem, and there is no effective algorithm (complexity O (2 ^ n )).


Continuous areas that are separated by walls and contain open spaces are called blocks ". Obviously, only one robot can be placed in one block. Compile these blocks, as shown in 7.25 (. It should be noted that there are two open spaces in the last line, that is, the second line, but there is no wall between the two open spaces and only grass, so the two open spaces should belong to the same "Block ". Similarly, add the blocks in the vertical direction to the number, as shown in 7.25 (B.


Consider each horizontal block as the vertex in vertex set X in a two-part graph, and the vertical block as the vertex in set Y. If two blocks have public spaces (note, each two blocks can have a maximum of one public space. For example, horizontal Block 2 and Vertical Block 1 have public spaces (2, 0), so there is an edge between vertex 2 in the X set and vertex 1 in the Y set. In this way, the problem is transformed into a two-part diagram, as shown in Figure 7.25 (c.

Because each edge represents an open space (that is, a horizontal block and a Public Open Space in a Vertical Block), Public vertices must exist between conflicting open spaces. For example, the side (x1, y1) indicates the open space (0, 0), the side (x2, y1) indicates the open space (2, 0), and the robot cannot be placed on the two open spaces at the same time. Therefore, the problem is converted to finding the largest edge set without common vertices in a two-part graph, which is the biggest matching problem.

Next, we will take the map shown in 7.23 (a) as an example to explain the construction process of the second graph: In the following code, the two-dimensional arrays xs and ys are used to numbers the blocks in the water supply square direction and vertical direction, respectively, as shown in the result 7.26 (B) and (c; the two-dimensional array g is used to connect blocks in the horizontal direction and in the vertical direction. If two blocks have public open spaces, the edge is connected between them, if g [I] [j] = 1, the I block in the horizontal direction has a public space and the j Block in the vertical direction needs to be connected; the result (d) after the EDGE connection is shown; the structure of the two diagram (e) is shown.


If the number starts to increase from 0, the maximum matching value is 7.27 (a). The groove edge indicates the matching edge.
Assume that the given initial match (as shown in 7.27 (B) is extended (you can assign values to arrays x and y before finding the maximum match). The process is as follows: starting from vertex x1, find the augmented path, and its adjacent vertex y1 has been matched. Therefore, we use y1 to match the vertex x2 and Recursively search for the augmented path. The adjacent vertex y2 of x2 does not match, therefore, we can find a augmented path (x1, y1, x2, y2). Following this augmented path, we can add 1 to the current match according to the Hungary algorithm. The improved match is the maximum match.


(The above content is excerpted by Wang Guiping, Wang Yan, and Ren Jiachen in graph theory, implementation, and application)


Although the explanation is a little long, it is very detailed. I used the adjacent table and Hopcroft-Karp to increase the size of the question according to the ideas in the book .. If many edges are added in extreme cases, it is a dense graph. The pointers and int values in the adjacent table may occupy more memory than an adjacent matrix, the good question is that ZOJ only gives 32 M memory .. 64 m can be used to write data in the adjacent table. I first ignored two int values in the adjacent table, and thought it was Hopcroft-Karp's extended multi-open array with super memory, just use the same DFS extended as in the book.


# Include <cstring> # include <string> # include <fstream> # include <iostream> # include <iomanip> # include <cstdio> # include <cctype> # include <algorithm> # include <queue> # include <map> # include <set> # include <vector> # include <stack> # include <ctime> # include <cstdlib> # include <functional> # include <cmath> using namespace std; # define PI acos (-1.0) # define MAXN 2001000 # define eps 1e-7 # define INF 0x7FFFFFFF # define LLINF 0x7FFFFFFFFFF FFFFF # define seed 1313131 # define MOD 1000000007 # define ll long # define ull unsigned ll # define lson l, m, rt <1 # define rson m + 1, r, rt <1 | 1int vis [2510]; int cnt, n1, n2; // n1 horizontal block count, n2 Vertical Block count int mx [2510], my [2510]; // The Edge connecting to the left vertex I in the mx maximum match, and the edge connecting to the right vertex I in the my maximum match int xs [60] [60], ys [60] [60], g [2510] [2510]; bool Find (int u) {int I, j; for (I = 1; I <= n2; I ++) {if (! Vis [I] & g [u] [I]) {vis [I] = 1; if (! My [I] | Find (my [I]) {mx [u] = I; my [I] = u; return true ;}} return false ;} int matching () {int I, j; memset (mx, 0, sizeof (mx); memset (my, 0, sizeof (my); int ans = 0; for (I = 1; I <= n1; I ++) {if (! Mx [I]) {memset (vis, 0, sizeof (vis); if (Find (I) ans ++ ;}} return ans ;} char mapp [60] [60]; int main () {int I, j, t, cas = 1, m, n; int number; int flag; scanf ("% d", & t); while (t --) {memset (xs, 0, sizeof (xs); memset (ys, 0, sizeof (ys); scanf ("% d", & m, & n); for (I = 0; I <m; I ++) scanf ("% s", mapp [I]); number = 0; for (I = 0; I <m; I ++) {flag = 0; for (j = 0; j <n; j ++) {if (mapp [I] [j] = 'O') {if (! Flag) number ++; xs [I] [j] = number; flag = 1;} else if (mapp [I] [j] = '#') flag = 0 ;}} n1 = number; number = 0; for (j = 0; j <n; j ++) {flag = 0; for (I = 0; I <m; I ++) {if (mapp [I] [j] = 'O') {if (! Flag) number ++; ys [I] [j] = number; flag = 1;} else if (mapp [I] [j] = '#') flag = 0 ;}} n2 = number; memset (g, 0, sizeof (g); for (I = 0; I <m; I ++) {for (j = 0; j <n; j ++) {if (xs [I] [j]) g [xs [I] [j] [ys [I] [j] = 1 ;}} printf ("Case: % d \ n", cas ++ ); int ans = matching (); printf ("% d \ n", ans);} return 0 ;}





Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.