zoukankan      html  css  js  c++  java
  • 引爆炸弹——DFS&&联通块

    题目

    链接

    在一个$n imes m$方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。

    现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。

    解决方案

    由于炸弹连锁,问题等价于求图中的联通块,只是此处的不只是相邻的炸弹联通,同行或同列也是广义的联通。

    值得注意的是,寻找“相邻”炸弹时不能挨个查找(会超时),需要先预处理每个炸弹的“东”、“西”、“南”、“北”相邻炸弹的位置。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 1000 + 10;
     5 const int maxm = 1000 + 10;
     6 int n,m;
     7 bool maze[maxn][maxm];
     8 bool r[maxn], c[maxm];
     9 char s[maxm];
    10 int dn[maxn][maxm], ds[maxn][maxm], dw[maxn][maxm], de[maxn][maxm];
    11 
    12 void init()
    13 {
    14     //memset(dn, -1, sizeof(dn));
    15     //memset(ds, -1, sizeof(ds));
    16     //memset(dw, -1, sizeof(dw));
    17     //memset(de, -1, sizeof(de));
    18     for(int j = 0;j < m;j++)
    19     {
    20         int flagn = -1;
    21         for(int i = 0;i < n;i++)
    22         {
    23             dn[i][j] = flagn;
    24             if(maze[i][j] == 1)  flagn = i;
    25         }
    26     }
    27 
    28     for(int j = 0;j < m;j++)
    29     {
    30         int flags = -1;
    31         for(int i = n-1;i >= 0;i--)
    32         {
    33             ds[i][j] = flags;
    34             if(maze[i][j] == 1)  flags = i;
    35         }
    36     }
    37 
    38     for(int i = 0;i < n;i++)
    39     {
    40         int flagw = -1;
    41         for(int j = 0;j < m;j++)
    42         {
    43             dw[i][j] = flagw;
    44             if(maze[i][j] == 1)  flagw = j;
    45         }
    46     }
    47 
    48     for(int i = 0;i < n;i++)
    49     {
    50         int flage = -1;
    51         for(int j = m - 1;j >= 0;j--)
    52         {
    53             de[i][j] = flage;
    54             if(maze[i][j] == 1)  flage = j;
    55         }
    56     }
    57 }
    58 
    59 int cnt = 0;
    60 void dfs(int i, int j)
    61 {
    62     //printf("%d %d
    ", i, j);
    63     maze[i][j] = 0;
    64     r[i] = c[j] = true;
    65 
    66     if(dn[i][j] != -1 && maze[dn[i][j]][j] == 1)  dfs(dn[i][j], j);
    67     if(ds[i][j] != -1 && maze[ds[i][j]][j] == 1)  dfs(ds[i][j], j);
    68     if(dw[i][j] != -1 && maze[i][dw[i][j]] == 1)  dfs(i, dw[i][j]);
    69     if(de[i][j] != -1 && maze[i][de[i][j]] == 1)  dfs(i, de[i][j]);
    70 
    71 }
    72 
    73 
    74 int main()
    75 {
    76     scanf("%d%d", &n,&m);
    77     for(int i = 0;i < n;i++)
    78     {
    79         scanf("%s", s);
    80         for(int j = 0;j < m;j++)  maze[i][j] = s[j] - '0';
    81     }
    82 
    83     init();
    84 
    85     int ans = 0;
    86     for(int i = 0;i <n;i++)
    87         for(int j = 0;j < m;j++)
    88         {
    89             if(maze[i][j] == 1 && (!r[i]) && (!c[j]))  //出现过的行和列肯定不可能再存在“未爆炸”的炸弹
    90             {
    91                 dfs(i, j);
    92                 ans++;
    93             }
    94         }
    95     printf("%d
    ", ans);
    96 
    97     return 0;
    98 }
  • 相关阅读:
    Ruby gem命令
    C语言中的static关键字
    Linux下clock计时函数学习
    open-falcon之dashboardportal说明.md
    open-falcon之graph
    open-falcon之query
    open-falcon之HBS
    open-falcon之judge
    open-falcon之transfer
    open-falcon之agent
  • 原文地址:https://www.cnblogs.com/lfri/p/11134915.html
Copyright © 2011-2022 走看看