Alas, it's the same modeling as God, which is totally unexpected.
The question is to give you a piece of land with open spaces, lawns, and obstacles. Then, let you put robots on it. robots can only be placed on the open space. Robots can launch attacks in the upper, lower, and left directions. Robot attacks can pass through the grass but cannot pass through the barrier. Ask how many robots you can hold at most without being attacked by robots.
I think the general idea should be like this. First of all, I will take it for granted that I want to connect the sides of the open space that can attack each other and then find the largest independent set, but the biggest independent set is hard to find, so we need to find a way to convert it into the biggest matching problem.
Therefore, if you want to change an open space into an edge, first an open space must have its own horizontal and vertical coordinates, which can be expressed as the two paths on the intersection graph. In addition, if two open spaces are in the same row or column, and there are no obstacles in the middle, you must put at most one robot and treat it as a blank space. In this way, we can split and label the original rows and columns. Traverse the intersection of all rows and columns. If the intersection is empty, a bidirectional edge from the number of rows to the number of the column is created, a bipartite graph is created.
Each vertex in the bipartite graph represents an area on a row or column. Only one robot can be placed in this area, and only one robot can be placed in the two connected points, in this way, the problem of Maximizing matching is successfully converted.
In addition, pay attention to the output of this question when the non-mainstream case: 1, the colon is in front of, at first written as Case 1: Crazy wa, really awesome
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>using namespace std;typedef long long LL;const int maxn = 61;const int maxk = maxn * maxn;char buf[maxn][maxn];int bx[maxk],by[maxk],n,m,cntx,cnty;int xid[maxn][maxn],yid[maxn][maxn];bool g[maxk][maxk],vis[maxk];int dfs(int now) { for(int i = 1;i <= cnty;i++) if(g[now][i] && !vis[i]) { vis[i] = true; if(!by[i] || dfs(by[i])) { bx[now] = i; by[i] = now; return 1; } } return 0;}int solve() { int ret = 0; memset(bx,0,sizeof(bx)); memset(by,0,sizeof(by)); for(int i = 1;i <= cntx;i++) if(!bx[i]) { memset(vis,0,sizeof(vis)); ret += dfs(i); } return ret;}int main() { int T; scanf("%d",&T); for(int kase = 1;kase <= T;kase++) { scanf("%d%d",&n,&m); for(int i = 1;i <= n;i++) scanf("%s",buf[i] + 1); //build-graph memset(xid,0,sizeof(xid)); memset(yid,0,sizeof(yid)); memset(g,0,sizeof(g)); cntx = cnty = 0; for(int i = 1;i <= n;i++) { int flag = 0; for(int j = 1;j <= m;j++) { if(buf[i][j] == ‘o‘) { if(flag == 0) cntx++,flag = 1; xid[i][j] = cntx; } else if(buf[i][j] == ‘#‘) flag = 0; } } for(int j = 1;j <= m;j++) { int flag = 0; for(int i = 1;i <= n;i++) { if(buf[i][j] == ‘o‘) { if(!flag) cnty++,flag = 1; yid[i][j] = cnty; } else if(buf[i][j] == ‘#‘) flag = 0; } } for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) if(xid[i][j] && yid[i][j]) { g[xid[i][j]][yid[i][j]] = true; } } int ans = solve(); printf("Case :%d\n%d\n",kase,ans); } return 0;}