zoukankan      html  css  js  c++  java
  • 用dfs遍历联通块(优化)

    一、题目(CF 598D)

    输入一个n x m的字符矩阵,求从某个空点出发,能碰到多少面墙壁,总共询问k次。(3 ≤m,n ≤1000,1 ≤ k ≤ min(nm,100 000)) 

    二、解题思路

    用DFS找连通分量:从每个“.”格子出发,递归遍历与之相邻的“*”格子,且写上相同的联通分量(即代码中的blocks数组),同时统计该联通分量边界墙壁面数。由于存在多次查询,我们用blocks[i][j]记录格子(i,j)所在的联通分量标号,用res[i]表示联通分量i的边界墙壁面数。

    三、代码实现

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 #include<stdbool.h>
     5 using namespace std;
     6 
     7 const int maxn = 1000 + 10;
     8 const int maxm = 1000 + 10;
     9 const int maxk = 100000 + 10;
    10 const int maxx = 1000000 + 10;
    11 int n, m;
    12 char maze[maxn][maxm];
    13 bool vis[maxn][maxm];
    14 int blocks[maxn][maxm];
    15 int res[maxx];
    16 int dx[] = { -1,0,1,0 }, dy[] = { 0,1,0,-1 };
    17 int flag = 0;
    18 
    19 void dfs(int x, int y, int flag,int& sum)   //sum传引用
    20 {
    21     vis[x][y] = true;
    22     blocks[x][y] = flag;
    23     for (int i = 0; i < 4; i++)
    24     {
    25         int xx = x + dx[i]; int yy = y + dy[i];
    26         if (xx >= 0 && xx < n && yy >= 0 && yy < m && (!vis[xx][yy]))
    27         {
    28             if (maze[xx][yy] == '*')
    29                 sum++;
    30             else
    31                 dfs(xx, yy, flag,sum);
    32         }
    33     }
    34 }
    35 int main()
    36 {
    37     int k;
    38     scanf("%d%d%d", &n, &m, &k);
    39     memset(vis, 0, sizeof(vis));
    40 
    41     for (int i = 0; i < n; i++)
    42         for (int j = 0; j < m; j++)
    43             cin >> maze[i][j];
    44 
    45     for (int i = 0; i < n; i++)
    46         for (int j = 0; j < m; j++)
    47         {
    48             if (maze[i][j] == '.' && (!vis[i][j]))
    49             
    50             {
    51                 int sum = 0;
    52                 dfs(i, j, ++flag,sum);
    53                 res[flag] = sum;
    54             }
    55         }
    56 
    57     while (k--)
    58     {
    59         int sx, sy;
    60         scanf("%d%d", &sx, &sy);
    61         printf("%d
    ", res[blocks[sx - 1][sy - 1]]);
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    18个功能强大的HTML5 和JavaScript游戏引擎库
    10 个超棒的 jQuery 视频插件
    HTML5播放视频音频
    CSS代码重构与优化之路
    推荐10款web前端的 HTML5 开发框架和开发工具
    JS中日期相关函数
    技术笔记1:java.sql.SQLException: Access denied for user 'root'@'localhost' (using password)
    图解HTTP阅读笔记(1)-网络基础TCP/IP
    框架和设计模式的区别
    SSH与MVC
  • 原文地址:https://www.cnblogs.com/lfri/p/9655368.html
Copyright © 2011-2022 走看看