地址 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 */
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 }