算法问题实战策略 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

猜你喜欢

转载自www.cnblogs.com/itdef/p/12503147.html
今日推荐