算法问题实战策略 Bishops 二分匹配

地址 https://algospot.com/judge/problem/read/BISHOPS

 

 

 

 

 

 

解答 使用二分匹配

 

 

  1 // 11111.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2 //
  3 
  4 #include <iostream>
  5 #include <vector>
  6 #include <string>
  7 #include <memory.h>
  8 
  9 
 10 using namespace std;
 11 
 12 const int MAX_N = 64, MAX_M = 64;
 13 
 14 //A B中的顶点个数
 15 int n, m;
 16 
 17 //adj[i][j] =Ai和Bj是否 相连
 18 bool adj[MAX_N][MAX_M];
 19 
 20 //保存与各顶点匹配的相应顶点的序号
 21 vector<int> aMatch, bMatch;
 22 
 23 //dfs()访问与否
 24 vector<bool> visited;
 25 
 26 //找出从A中顶点a连接到B中尚未匹配的顶点的路径
 27 bool dfs(int a) {
 28     if (visited[a]) return false;
 29     visited[a] = true;
 30     for (int b = 0; b < m; ++b) {
 31         if (adj[a][b]) {
 32             //b尚未匹配时 从bMatch[b]起始寻找 增广路径
 33             if (bMatch[b] == -1 || dfs(bMatch[b])) {
 34                 //发现增广路径 把 a和b互相匹配
 35                 aMatch[a] = b;
 36                 bMatch[b] = a;
 37                 return true;
 38             }//if (bMatch[b] == -1 || dfs(bMatch[b])) {
 39         }//if (adj[a][b]) {
 40     }
 41 
 42     return false;
 43 }
 44 
 45 
 46 //计算aMatch与bMatch后返回最大匹配的大小
 47 int bipartiteMatch() {
 48     //所有顶点起始均未连接
 49     aMatch = vector<int>(n, -1);
 50     bMatch = vector<int>(m, -1);
 51 
 52     int size = 0;
 53     for (int start = 0; start < n; ++start) {
 54         visited = vector<bool>(n, false);
 55         //利用深度优先搜索找出从start起始的增广路径
 56         if (dfs(start))
 57             ++size;
 58     }
 59     return size;
 60 }
 61 
 62 
 63 //=================================================
 64 const int dx[2] = { -1,1 };
 65 const int dy[2] = { 1,1 };
 66 
 67 vector<string> board;
 68 
 69 int id[2][8][8];
 70 
 71 int placeBishops() {
 72     memset(id, -1, sizeof id);
 73     int count[2] = { 0,0 };
 74     for (int dir = 0; dir < 2; ++dir) {
 75         for (int y = 0; y < board.size(); ++y) {
 76             for (int x = 0; x < board.size(); ++x) {
 77                 if (board[y][x] == '.' && id[dir][y][x] == -1) {
 78                     int cy = y, cx = x;
 79                     while (0 <= cy && cy < board.size() &&
 80                         0 <= cx && cx < board.size() &&
 81                         board[cy][cx] == '.') {
 82                         id[dir][cy][cx] = count[dir];
 83                         cy += dy[dir];
 84                         cx += dx[dir];
 85                     }
 86                     count[dir]++;
 87                 }
 88             }
 89         }
 90     }
 91 
 92     n = count[0];
 93     m = count[1];
 94     memset(adj, 0, sizeof adj);
 95     for (int y = 0; y < board.size(); ++y) {
 96         for (int x = 0; x < board.size(); ++x) {
 97             if (board[y][x] == '.')
 98                 adj[id[0][y][x]][id[1][y][x]] = 1;
 99         }
100     }
101 
102     return bipartiteMatch();
103 }
104 
105 vector<int> ans;
106 int main()
107 {
108     int a,b;
109     cin >> a;
110 
111     while (a--) {
112         cin >> b;
113         board.clear();
114         for (int i = 0; i < b; i++) {
115             string s;
116             cin >> s;
117             board.push_back(s);
118         }
119 
120         ans.push_back(placeBishops());
121     }
122 
123     for (auto & e : ans) {
124         cout << e << endl;
125     }
126 }
127 
128 /*
129 .....
130 .....
131 .....
132 .....
133 .....
134 */
View Code

 

  1 #include <iostream>
  2 #include <vector>
  3 #include <memory.h>
  4 #include <string>
  5 
  6 
  7 using namespace std;
  8 /*
  9 3
 10 5
 11 .....
 12 .....
 13 .....
 14 .....
 15 .....
 16 8
 17 ..**.*.*
 18 **.***.*
 19 *.**...*
 20 .*.**.**
 21 *.**.*.*
 22 ..**.*.*
 23 ...*.*.*
 24 **.*.*.*
 25 8
 26 *.*.*.*.
 27 .*.*.*.*
 28 *.*.*.*.
 29 .*.*.*.*
 30 *.*.*.*.
 31 .*.*.*.*
 32 *.*.*.*.
 33 .*.*.*.*
 34 예제 출력
 35 8
 36 18
 37 7
 38 */
 39 
 40 const int MAX_N = 70;
 41 
 42 
 43 //adj[i][j] =Ai和Bj是否 相连
 44 bool adj[MAX_N][MAX_N];
 45 
 46 vector<string> board;
 47 string s;
 48 
 49 int t; int ans;
 50 int m, n;
 51 
 52 int id[2][MAX_N][MAX_N];
 53 
 54 vector<int> aMatch, bMatch;
 55 
 56 vector<bool> visited;
 57 
 58 
 59 bool dfs(int a)
 60 {
 61     if (visited[a]) return false;
 62 
 63     visited[a] = true;
 64 
 65     for (int b = 1; b <= n; b++) {
 66         if (adj[a][b]) {
 67             //b尚未匹配时 从bMatch[b]起始寻找 增广路径
 68             if (bMatch[b] == -1 || dfs(bMatch[b])) {
 69                 aMatch[a] = b;
 70                 bMatch[b] = a;
 71                 return true;
 72             }
 73         }
 74     }
 75 
 76     return false;
 77 }
 78 
 79 
 80 int MaxMatch()
 81 {
 82     //所有顶点起始均未连接
 83     aMatch = vector<int>(m + 1, -1);
 84     bMatch = vector<int>(n + 1, -1);
 85 
 86     int size = 0;
 87 
 88     for (int start = 1; start <= m; ++start) {
 89         visited = vector<bool>(m + 1, false);
 90         if (dfs(start))
 91             ++size;
 92     }
 93 
 94     return size;
 95 }
 96 
 97 int PlaceRobot()
 98 {
 99     memset(id, -1, sizeof id);
100     int count[2] = { 0 };
101     int dir = 0;
102     //0左斜  1右斜
103 
104     for (int i = 0; i < m; i++) {
105         for (int j = 0; j < m; j++) {
106             if (board[i][j] == '.' && id[dir][i][j] == -1) {
107                 count[dir]++;
108                 int ci = i; int cj = j;
109                 while (ci >= 0 && ci < m && cj >= 0 && cj < m && board[ci][cj] == '.') {
110                     id[dir][ci][cj] = count[dir];
111                     ci += 1; cj += -1;
112                 }
113             }
114         }
115     }
116 
117     dir = 1;
118     for (int i = 0; i < m; i++) {
119         for (int j = 0; j < m; j++) {
120             if (board[i][j] == '.' && id[dir][i][j] == -1) {
121                 count[dir]++;
122                 int ci = i; int cj = j;
123                 while (ci >= 0 && ci < m && cj >= 0 && cj < m && board[ci][cj] == '.') {
124                     id[dir][ci][cj] = count[dir];
125                     ci += 1; cj += 1;
126                 }
127             }
128         }
129     }
130 
131     m = count[0]; n = count[1];
132     memset(adj, 0, sizeof adj);
133 
134     for (int i = 0; i < board.size(); i++) {
135         for (int j = 0; j < board[0].size(); j++) {
136             if (board[i][j] == '.') {
137                 adj[id[0][i][j]][id[1][i][j]] = 1;
138             }
139         }
140     }
141 
142     return MaxMatch();
143 }
144 
145 int main()
146 {
147     cin >> t;
148     vector<int> v;
149     for (int k = 1; k <= t; k++) {
150         cin >> m;
151         n = m;
152         board.clear();
153         for (int i = 0; i < m; i++) {
154             cin >> s;
155             board.push_back(s);
156         }
157 
158         v.push_back(PlaceRobot());
159     }
160 
161     for (auto e : v) {
162         cout << e << endl;
163     }
164 
165     return 0;
166 }

 

posted on 2020-03-16 12:54  itdef  阅读(178)  评论(0编辑  收藏  举报

导航