• 算法问题实战策略 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 }
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    绝对路径和相对路径
    基本的文件操作
    Python2和3字符编码区别
    java开发两年了,连个java代理模式都摸不透,你怎么跳槽涨薪?
    【建议收藏】阿里P7总结的Spring注解笔记,把组件注册讲的明明白白
    面试官:你说你精通SpringBoot,你给我说一下类的自动装配吧
    面试BAT问的最多的27道MyBatis 面试题(含答案和思维导图总结)
    Springboot 框架整理,建议做开发的都看看,整理的比较详细!
    直面秋招!非科班生背水一战,最终拿下阿里等大厂offer!
    写的太细了!Spring MVC拦截器的应用,建议收藏再看!
  • 原文地址:https://www.cnblogs.com/itdef/p/12503147.html
Copyright © 2020-2023  润新知