Uva572(DFS+联通集)

题目地址

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=838&page=show_problem&problem=513

题目分析

就是搜索一个二维数组里面的'@'联通集,并求联通集的个数,做法是:用二维数组存储输入的字符,然后找dfs()的第一个起点,因为不是有向图所以可以从二维数组的第一个'@'开始进行dfs()搜索。dfs()的写法就是递归,因为要求递归找到对应起点的所有子孙并标上序号,所以还需要一个idx[][]去存储每个'@'的所属连通集序号。dfs()写法中递归的条件也是需要注意的,具体的要求是:

  • 点在二维数组范围内
  • 点没有被标号为某个联通集序号
  • 点为'@'

代码:

#include <bits/stdc++.h>
using namespace std;

const int maxn = 210;
int m,n;
char buf[maxn][maxn];
int idx[maxn][maxn];

bool inside(int r,int c){
    if(r < 0 || r >= m || c < 0 || c >= n) return false;
    return true;
}
void dfs(int r,int c ,int id){
    idx[r][c] = id;
    for(int dr = -1;dr <= 1;dr++){
        for(int dc = -1;dc <= 1;dc++){
            if(dr != 0 || dc != 0){     //扫描的结点不是本身 
                if(inside(r+dr,c+dc) && idx[r+dr][c+dc] == 0 && buf[r+dr][c+dc] == '@')     //周边的结点满足条件则递归:1:不越界,2:没有被标号;3:为'@' 
                    dfs(r+dr,c+dc,id);
            }
        }
    }
}
int main(void){
    while(scanf("%d%d",&m,&n) == 2 && m && n){
        for(int i = 0;i < m;i++){
            scanf("%s",buf[i]);
        }
        
        memset(idx,0,sizeof(idx));
        int cnt = 0;
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                if(buf[i][j] == '@' && idx[i][j] == 0)
                    dfs(i,j,++cnt);     //深度优先搜索 
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Western-Trail/p/9180795.html