zoukankan      html  css  js  c++  java
  • ICPC Pacific Northwest Regional Contest 2016 Maximum Islands(二分图最大独立集)

    Maximum Islands

    思路:预处理‘L’周围包围‘W’。‘L’独自成为岛屿为最优,我们‘L’,‘W’交替处理的图((x+y)%2为同一个集合),分为两个集合,相邻的‘L’和‘W’有边,同一个集合没边,变成二分图的最大独立集问题,得出最多的互不相邻的点就是最大岛屿数量。因为我们匹配的出发点是全图,所以匹配数 = match / 2。

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <vector>
      5 #include <queue>
      6 
      7 using namespace std;
      8 
      9 const int N = 50;
     10 int mv_x[] = {1, -1, 0, 0};
     11 int mv_y[] = {0, 0, 1, -1};
     12 char mp[N][N]; //地图
     13 vector<int > E[N * N]; //
     14 int pre[N * N]; 
     15 bool vis[N * N];
     16 bool viss[N][N]; //是否访问过
     17 bool e[N * N][N * N]; //重复边判定
     18 int id[N][N]; //编号
     19 int n, m, island, poi;
     20 
     21 inline bool check(int x, int y)
     22 {
     23     return x >= 0 && x < n && y >= 0 && y < m;
     24 }
     25 
     26 void dfs_island(int x, int y)
     27 {
     28     mp[x][y] = 'W';
     29     for(int p = 0; p < 4; ++p){
     30         int dx = x + mv_x[p];
     31         int dy = y + mv_y[p];
     32 
     33         if(check(dx, dy) && mp[dx][dy] == 'L'){
     34             dfs_island(dx, dy);
     35         }
     36     }
     37 }
     38 
     39 inline void add(int u, int v)
     40 {
     41     E[u].push_back(v);
     42     E[v].push_back(u);
     43 }
     44 
     45 void dfs_cloud(int x, int y)
     46 {
     47     viss[x][y] = 1;
     48     for(int p = 0; p < 4; ++p){
     49         int dx = x + mv_x[p];
     50         int dy = y + mv_y[p];
     51 
     52         if(check(dx, dy) && mp[dx][dy] == 'C'){
     53             int id1 = min(id[x][y], id[dx][dy]);
     54             int id2 = max(id[x][y], id[dx][dy]);
     55             if(e[id1][id2] == 0){
     56                 e[id1][id2] = 1;
     57                 add(id1, id2);
     58             }
     59             if(!viss[dx][dy]){
     60                 viss[dx][dy] = 1;
     61                 dfs_cloud(dx, dy);
     62             }      
     63         }
     64     }
     65 }
     66 
     67 bool find(int u)
     68 {
     69     for(auto v : E[u]){
     70         if(vis[v]) continue;
     71         vis[v] = 1;
     72         if(!pre[v] || find(pre[v])){
     73             pre[v] = u;
     74             return true;
     75         }
     76     }
     77     return false;
     78 }
     79 
     80 void show()
     81 {
     82     for(int i = 0; i < n; ++i){
     83         for(int j = 0; j < m; ++j){
     84             cout << mp[i][j];
     85         }cout << endl;
     86     }
     87 }
     88 
     89 void solve()
     90 {
     91 
     92     scanf("%d%d", &n, &m);
     93     for(int i = 0; i < n; ++i) scanf("%s", &mp[i]);
     94     //预处理L
     95     for(int i = 0; i < n; ++i){
     96         for(int j = 0; j < m; ++j){
     97             if(mp[i][j] == 'L'){
     98                 for(int p = 0; p < 4; ++p){
     99                     int dx = i + mv_x[p];
    100                     int dy = j + mv_y[p];
    101                     if(check(dx, dy) && mp[dx][dy] == 'C'){
    102                         mp[dx][dy] = 'W';
    103                     }
    104                 }
    105             }
    106         }
    107     }
    108 
    109     //统计岛屿个数,编号
    110     for(int i = 0; i < n; ++i){
    111         for(int j = 0; j < m; ++j){
    112             if(mp[i][j] == 'L'){
    113                 island++;
    114                 dfs_island(i, j);
    115             }else if(mp[i][j] == 'C') id[i][j] = ++poi;
    116         }
    117     }
    118 
    119     //建图
    120     for(int i = 0; i < n; ++i){
    121         for(int j = 0; j < m; ++j){
    122             if(mp[i][j] == 'C'){
    123                 dfs_cloud(i, j);
    124             }
    125         }
    126     }
    127 
    128     //匹配
    129     int match = 0;
    130     for(int i = 0; i < n; ++i){
    131         for(int j = 0; j < m; ++j){
    132             if(!id[i][j]) continue;
    133             for(int x = 1; x <= poi; ++x) vis[x] = 0; 
    134             if(find(id[i][j])) match++;
    135         }
    136     }
    137 
    138     //printf("island = %d
    ", island + poi - match / 2);
    139     printf("%d
    ", island + poi - match / 2);
    140 }
    141 
    142 
    143 int main()
    144 {
    145 
    146     solve();
    147 
    148     return 0;
    149 }
  • 相关阅读:
    使用idea进行远程调试
    map根据属性排序、取出map前n个
    编写shell脚本一键启动 重启 停止springboot jar包
    IDEA给类和方法配置注释模板(参数换行显示)
    springboot文件上传报错
    WebMvcConfigurer 与 WebMvcConfigurationSupport避坑指南
    WebMvcConfigurerAdapter详解和过时后的替代方案
    springboot上传文件过大,全局异常捕获,客户端没有返回值
    javascript中Math.random()产生随机数总结
    关于微信中的localStorage及使用cookie的解决方案
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/13214334.html
Copyright © 2011-2022 走看看