ZOJ 1654 Place the Robots graph Creation Thinking (Block thinking) + binary matching, zojrobots
Question link: http://acm.zju.edu.cn/onlinejudge/showProblem.do? ProblemId = 654
AC one hundred questions, not as comfortable as AC!
Question: An n * m map, * represents the lawn, # represents the wall, o represents the open space, and the o in the figure is placed in the robot. The robot can attack (up and down) in four directions, the attack range is infinite, and robots cannot attack each other. Robots cannot be placed on lawns, and attacks on robots can pass through lawns. However, attacks on robots cannot pass through the walls, for example, the "* o # o" line can contain two robots, and the "o * oo" line can only contain one. How many robots can be put at most?
I just learned the bipartite graph. I have made a few questions about the bipartite graph and don't need to practice it. After reading the question, I know that it is the largest independent set of the Bipartite Graph, however, the difficulty is how to create a graph.
I did not have any idea about this question I read last night. I thought about it again after I went back to the dormitory. I thought about how to create a diagram. Today I typed it and WA ran it n times. I checked the problem, there is no error in creating a graph. I just missed a point that only horizontal parts are used as the X set, and the remaining points are the Y set by default...
Ideas: Uses the idea of block to create a graph. What is block? The block attack scope can be achieved by one piece. "o * oo" is the block, and it is also one piece. "* o # o" is the two pieces, in layman's terms, this line of a map is separated by a wall and the continuous area with open space is called a "Block". Of course, according to the question, only one robot can be placed in one block, this is also true for vertical parts. blocks are numbered. All numbers of horizontal parts are X sets, and all numbers of vertical parts are Y sets, of course, if the same "o" point is numbered twice, you can just create an edge.
Result Accepted ID |
1654 Language |
C ++ Time |
60 Memery |
26720 |
Include <iostream> # include <cstdio> # include <cstdlib> # include <cstring> # include <algorithm> # include <math. h> # define init (a) memset (a, 0, sizeof (a) # define PI acos (-1, 0) using namespace std; const int maxn = 55; const int maxm = 2600; # define lson left, m, id <1 # define rson m + 1, right, id <1 | 1 # define min (a, B) (a> B )? B: a # define max (a, B) (a> B )? A: bint mar [maxn] [maxn], mac [maxn] [maxn]; int G [maxm] [maxm]; int line [maxm]; char MAP [maxn] [maxn]; bool vis [maxm]; int X, Y; int DFS (int u) {for (int v = 1; v <= Y; v ++) {if (G [u] [v] = 1 &&! Vis [v]) {vis [v] = 1; if (line [v] =-1 | DFS (line [v]) {line [v] = u; return 1 ;}} return 0 ;}int K_M () {memset (line,-1, sizeof (line )); int ans = 0; for (int I = 1; I <= X; I ++) {init (vis); ans + = DFS (I);} return ans ;} void Creat_G (int n, int m) {for (int I = 0; I <n; I ++) // horizontally split into X sets {for (int j = 0; j <m; j ++) {if (MAP [I] [j] = 'O') {X ++; while (j <m & MAP [I] [j]! = '#') {Mar [I] [j] = X; // the same open space or lawn number is j ++ ;}}}} for (int I = 0; I <m; I ++) // use vertical blocks as Y sets {for (int j = 0; j <n; j ++) {if (MAP [j] [I] = 'O') {Y ++; while (j <n & MAP [j] [I]! = '#') {Mac [j] [I] = Y; j ++ ;}}} int main () {int t, n, m; scanf ("% d", & t); for (int Case = 1; Case <= t; Case ++) {init (G); init (mar ); init (mac); X = 0, Y = 0; scanf ("% d", & n, & m); for (int I = 0; I <n; I ++) scanf ("% s", MAP [I]); Creat_G (n, m); // block for (int I = 0; I <n; I ++) // create a graph {for (int j = 0; j <m; j ++) {if (MAP [I] [j] = 'O ') {G [mar [I] [j] [mac [I] [j] = 1; // connection between the building block and the block }}int ans = K_M (); printf ("Case: % d \ n", Case, ans );} return 0 ;}