ZOJ 1654 Place the Robots (super-Good idea)-from lanshui_Yang

Source: Internet
Author: User

Place the Robots

--------------------------------------------------------------------------------

Time Limit: 5 Seconds Memory Limit: 32768 KB

--------------------------------------------------------------------------------

Robert is a famous engineer. One day he was given a task by his boss. The background of the task was the following:

Given a map consisting of square blocks. there were three kinds of blocks: Wall, Grass, and Empty. his boss wanted to place as your robots as possible in the map. each robot held a laser weapon which cocould shoot to four direly LY (north, east, south, west) simultaneously. A robot had to stay at the block where it was initially placed all the time and to keep firing all the time. the laser beams certainly cocould pass the grid of Grass, but cocould not pass the grid of Wall. A robot cocould only be placed in an Empty block. surely the boss wocould not want to see one robot hurting another. in other words, two robots must not be placed in one line (horizontally or vertically) unless there is a Wall between them.

Now that you are such a smart programmer and one of Robert's best friends, He is asking you to help him solving this problem. that is, given the description of a map, compute the maximum number of robots that can be placed in the map.


Input

The first line contains an integer T (<= 11) which is the number of test cases.

For each test case, the first line contains two integers m and n (1 <= m, n <= 50) which are the row and column sizes of the map. then m lines follow, each contains n characters of '#', '*', or 'O' which represent Wall, Grass, and Empty, respectively.


Output

For each test case, first output the case number in one line, in the format: "Case: id" where id is the test case number, counting from 1. in the second line just output the maximum number of robots that can be placed in that map.


Sample Input

2
4
O ***
*###
Oo # o
* ** O
4
# Ooo
O # oo
Oo # o
***#


Sample Output

Case: 1
3
Case: 2
5

Given a map of m * n, a map consists of three squares: walls, lawns, and open spaces. It is required to place as many robots as possible in the map. Each robot is equipped with a laser gun and can be shot in four directions (Up, down, left, right) at the same time. The robot remains in the initial square and cannot be moved. Then, it keeps shooting in four directions. Laser shots can penetrate the lawn, but cannot penetrate the walls. Robots can only be placed in open spaces and cannot attack each other. Output the maximum number of robots that can be placed. 'O' indicates the open space, '#' indicates the wall, and '*' indicates the lawn.

Solution: This question is not easy to think about. The key is how to convert it into the biggest matching problem of the two-part graph, that is, how to create a graph.

The following details: the continuous areas that are separated by walls and contain open spaces are called blocks. Obviously, only one robot can be placed in one block. Note: In the same line, if there is no wall between the two open spaces and there is only grass, the two open spaces should belong to the same one ". Similarly, the blocks in the vertical direction are also numbered. Then, we regard each horizontal block as the vertex in vertex set X in the two graphs, and the vertical block as the vertex in set Y. If there is a public space between the two blocks (note, each two blocks can have a maximum of one public space. Because each edge represents a blank space, there must be public vertices between conflicting spaces, the problem is converted to finding the largest edge set without public vertices in the two graphs, that is, finding the maximum matching problem.

See the Code:

 

# Include <iostream> # include <cstring> # include <string> # include <cmath> # include <cstdio> # include <algorithm> using namespace std; const int MAXN = 55; int n, m; char map [MAXN] [MAXN]; short g [MAXN * MAXN] [MAXN * MAXN]; // The array must not be small, otherwise, WAF may be used directly !! // Use short or bool to avoid MLEint cx [MAXN * MAXN]; int cy [MAXN * MAXN]; struct Point {int br; int bc; Point (): br (-1), bc (-1) {}} s [MAXN * MAXN]; int ha [MAXN] [MAXN]; // auxiliary array bool vis [MAXN * MAXN]; // mark array int sumbr =-1; int sumbc =-1; void init () {memset (ha,-1, sizeof (ha); memset (g, 0, sizeof (g); memset (cx,-1, sizeof (cx); memset (cy,-1, sizeof (cy); sumbr =-1; // record the number of horizontal blocks sumbc =- 1; // record the number of vertical blocks scanf ("% d \ n", & n, & m); int I, j; for (I = 0; I <n; I ++) {scanf ("% s", map [I]) ;}int cnt = 0; int first =-1; for (I = 0; I <n; I ++) // horizontal block label, starting from 0 {first =-1; for (j = 0; j <m; j ++) {if (map [I] [j] = '#') {first =-1;} if (map [I] [j] = 'O ') {if (first =-1) {sumbr ++; first = 1 ;}s [cnt]. br = sumbr; ha [I] [j] = cnt; cnt ++ ;}}for (j = 0; j <m; j + +) // Label the Vertical Block, starting from 0 {first =-1; for (I = 0; I <n; I ++) {if (map [I] [j] = '#') {first =-1;} if (map [I] [j] = 'O ') {if (first =-1) {sumbc ++; first = 1;} int tmp = ha [I] [j]; s [tmp]. bc = sumbc ;}}for (I = 0; I <cnt; I ++) // create a graph {g [s [I]. br] [s [I]. bc] = 1 ;}} int ca = 0; int path (int v) // Hungarian algorithm {int I; for (I = 0; I <= sumbc; I ++) {if (g [v] [I] = 1 &&! Vis [I]) {vis [I] = true; if (cy [I] =-1 | path (cy [I]) {cy [I] = v; cx [v] = I; return 1 ;}}return 0 ;}void solve () {int I; int ans = 0; for (I = 0; I <= sumbr; I ++) {if (cx [I] =-1) {memset (vis, 0, sizeof (vis )); if (path (I) ans ++ ;}} printf ("Case: % d \ n", ++ ca); printf ("% d \ n ", ans);} int main () {int T; scanf ("% d", & T); while (T --) {init (); solve ();} return 0 ;}

 

Related Article

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.