The problem is a classic two-part matching problem. No two boats can be placed on the same column (row) unless an iceberg is separated. For this two-dimensional plan, it is easy to think of dividing the rows and columns into two sets, and then matching the two graphs, and when a row coordinate is matched to a column coordinate, the lattice can place the ship. So in order to make any two ships are not in the same row or the same column, unless there is an iceberg, we can each row in a row can only place a single ship of the area is set to a number, the same as the column is also processed, this is equivalent to the row and column indentation, followed by the maximum flow template set is OK.
There is a better algorithm for processing the binary graph, called the Hungarian algorithm, purple book did not, first use the maximum flow algorithm to solve it.
Purple Book 11 also has a similar topic, but more interesting portal
See the code for details:
#include <bits/stdc++.h>using namespace Std;const int maxn = 2*550*550;typedef long long ll;const int INF = 100000000 0;int t,n,m,id1[55][55],id2[55][55];struct Edge {int from, to, cap, flow;}; BOOL operator < (const edge& A, const edge& b) {return A.from < B.from | | (A.from = = B.from && a.to < b.to);} struct Dinic {int n, m, S, t; Vector<edge> old; Vector<edge> edges; Twice times the number of sides vector<int> G[MAXN]; adjacency table, G[i][j] indicates the ordinal of the J-side of the node I in the E-array of bool VIS[MAXN]; BFS using int D[MAXN]; Distance from starting point to I int CUR[MAXN]; Current arc pointer void init (int n) {for (int i = 0; i < n; i++) g[i].clear (); Edges.clear ();} void Addedge (int from, int to, int caps) {Edges.push_back (Edge) {from, to, Cap, 0}); Edges.push_back (Edge) {To, from, 0, 0}); m = Edges.size (); G[from].push_back (m-2); G[to].push_back (m-1);} BOOL BFS () {memset (Vis, 0, sizeof (VIS)); Queue<int> Q; Q.push (s); Vis[s] = 1; D[s] = 0; WhiLe (! Q.empty ()) {int x = Q.front (); Q.pop (); for (int i = 0; i < g[x].size (); i++) {edge& e = edges[g[x][i]]; if (!vis[e.to] && e.cap > E.flow) {vis[e.to] = 1; D[e.to] = d[x] + 1; Q.push (e.to); }}} return vis[t];} int DFS (int x, int a) {if (x = = T | | a = = 0) return A; int flow = 0, F; for (int& i = cur[x]; i < g[x].size (); i++) {edge& e = edges[g[x][i]]; if (d[x] + 1 = = D[e.to] && (f = DFS (e.to, Min (A, e.cap-e.flow))) > 0) {e.flow + = f; Edges[g[x][i]^1].flow-= f; Flow + + F; A-= f; if (a = = 0) break; }} return flow;} int Maxflow (int s, int t) {this->s = s; this->t = t; int flow = 0; while (BFS ()) {memset (cur, 0, sizeof (cur)); Flow + = DFS (s, INF); } return flow; }}g;map<int,int> P;char S[55][55];int Main () {scanf ("%d", &t); while (t--) {scanf ("%d%d", &n,&amP;M); G.init (MAXN); for (int i=1;i<=n;i++) scanf ("%s", s[i]+1); int cnt = 1; for (int i=1;i<=n;i++) {for (int j=1;j<=m;j++) {if (s[i][j] = = ' # ') id1[i][j] = cnt++; if (s[i][j] = = ' * ') id1[i][j] = cnt; } cnt++; } for (int j=1;j<=m;j++) {for (int i=1;i<=n;i++) {if (s[i][j] = = ' # ') id2[i][j] = cn t++; if (s[i][j] = = ' * ') id2[i][j] = cnt; } cnt++; } p.clear (); for (int i=1;i<=n;i++) {for (int j=1;j<=m;j++) {if (s[i][j] = = ' * ') {G. Addedge (id1[i][j],id2[i][j],1); if (!p.count (Id1[i][j])) {P[id1[i][j]] = 1; G.addedge (0,id1[i][j],1); } if (!p.count (Id2[i][j])) {P[id2[i][j]] = 1; G.addedge (id2[i][j],cnt+1, 1); }}}} int ans = G.maxflow (0,cnt+1); printf ("%d\n", ans); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU 5093 Battle ships (binary graph matching)