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;
}

补充一种和刘汝佳不同的做法,不需要存储联通块的序号,更加简单:

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

const int maxn = 210;
int m,n;
char buf[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){
	buf[r][c] = '*';		//将遍历过的所有连通块全部变为*;就可以不用存储连通块序号的数组了
	
	//循环遍历移动8个方向 
    for(int dr = -1;dr <= 1;dr++){
        for(int dc = -1;dc <= 1;dc++){
        	//判断(r+dr,c+dc)是不是在区域内,并且为油田 
           	if(inside(r+dr,c+dc) && buf[r+dr][c+dc] == '@')
           		dfs(r+dr,c+dc);
        }
    }
}

int main(void){
    while(scanf("%d%d",&m,&n) == 2 && m && n){
        for(int i = 0;i < m;i++){
            scanf("%s",buf[i]);
        }
        
        int cnt = 0;
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                if(buf[i][j] == '@')
                {
                	dfs(i,j);     
                    cnt++;
				}
            }
        }
        printf("%d\n",cnt);
    }
    return 0;
}
posted @ 2018-06-13 23:28  Western_Trail  阅读(199)  评论(0编辑  收藏  举报