[HDOJ5093] Battle ships(最大匹配)

题目链接:https://vjudge.net/problem/HDU-5093

按照行和列分别标注*的id,合并同行或同列相邻的块,二分图两部分分别是行和列,某一点(i,j)则连一条rid(i,j)到cid(i,j)的边。跑最大匹配。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 typedef struct pair<int, int> pii;
  5 const int maxn = 110;
  6 const int maxm = 3030;
  7 const int inf = 0x3f3f3f3f;
  8 
  9 int n, m;
 10 char mp[maxn][maxn];
 11 
 12 int nu, nv, dist;
 13 int Mx[maxm], My[maxm], dx[maxm], dy[maxm], vis[maxm], G[maxm][maxm];
 14 
 15 bool Dfs(int u){
 16   for(int v = 1; v <= nv; v++)
 17     if(!vis[v] && G[u][v] && dy[v] == dx[u] + 1){
 18       vis[v] = 1;
 19       if(My[v] != -1 && dy[v] == dist)
 20         continue;
 21       if(My[v] == -1|| Dfs(My[v])){
 22         My[v] = u;
 23         Mx[u] = v;
 24         return 1;
 25       }
 26     }
 27   return 0;
 28 }
 29 bool Search(){
 30   queue<int> Q;
 31   dist = inf;
 32   memset(dx, -1, sizeof(dx));
 33   memset(dy, -1, sizeof(dy));
 34   for(int i = 1; i <= nu; i++)
 35     if(Mx[i] == -1){
 36       Q.push(i);
 37       dx[i] = 0;
 38     }
 39   while(!Q.empty()){
 40     int u = Q.front();
 41     Q.pop();
 42     if(dx[u] > dist)
 43       break;
 44     for(int v = 1; v <= nv; v++)
 45       if(G[u][v] && dy[v] == -1){
 46         dy[v] = dx[u] + 1;
 47         if(My[v] == -1)
 48           dist = dy[v];
 49         else{
 50           dx[My[v]] = dy[v] + 1;
 51           Q.push(My[v]); 
 52         }
 53       } 
 54   }
 55   return dist != inf;
 56 }
 57 int MaxMatch() {
 58   int res = 0;
 59   memset(Mx, -1, sizeof(Mx));
 60   memset(My, -1, sizeof(My));
 61   while(Search()){
 62     memset(vis, 0, sizeof(vis));
 63     for(int i = 0; i < nu; i++)
 64       if(Mx[i] == -1&& Dfs(i))
 65         res++;
 66   }
 67   return res;
 68 }
 69 
 70 int rid[maxn][maxn], cid[maxn][maxn];
 71 
 72 
 73 int main() {
 74     // freopen("in", "r", stdin);
 75     int T;
 76     scanf("%d", &T);
 77     while(T--) {
 78         scanf("%d%d",&n,&m);
 79         for(int i = 0; i < n; i++) {
 80             scanf("%s", mp[i]);
 81         }
 82         memset(G, 0, sizeof(G));
 83         memset(rid, 0, sizeof(rid));
 84         memset(cid, 0, sizeof(cid));
 85         int cnt = 1;
 86         for(int i = 0; i < n; i++) {
 87             for(int j = 0; j < m; j++) {
 88                 if(mp[i][j] == '*') rid[i][j] = cnt;
 89                 if(mp[i][j] == '#') rid[i][j] = cnt++;
 90             }
 91             cnt++;
 92         }
 93         nu = cnt;
 94         cnt = 1;
 95         for(int j = 0; j < m; j++) {
 96             for(int i = 0; i < n; i++) {
 97                 if(mp[i][j] == '*') cid[i][j] = cnt;
 98                 if(mp[i][j] == '#') cid[i][j] = cnt++;
 99             }
100             cnt++;
101         }
102         nv = cnt;
103         for(int i = 0; i < n; i++) {
104             for(int j = 0; j < m; j++) {
105                 if(mp[i][j] == '*') {
106                     G[rid[i][j]][cid[i][j]] = 1;
107                 }
108             }
109         }
110         printf("%d
", MaxMatch());
111     }
112     return 0;
113 }
原文地址:https://www.cnblogs.com/kirai/p/6782833.html