UVA 572 搜索 初识BFS DFS

题目类型: 搜索

样例输入:

1 1
*
3 5
*@*@*
**@**
*@*@*
1 8
@@****@*
5 5
****@
*@@*@
*@**@
@@@*@
@@**@
0 0

样例输出:

0
1
2
2

分析:

这一题可以说是搜索中最基础的一题之一。 要找出相连在一起的有多少块, 因此, 依次枚举,遇到@时就进行搜索,用深搜,广搜都行,目的是把相连的@都标记为已访问。

下面给出用DFS(深搜)和BFS(广搜)的代码

DFS  1 :递推

#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

int m,n,idx[105][105];
char pic[105][105];

void dfs(int r,int c,int id)
{
    if (r<0 || r>=m || c<0 || c>= n)   return ;
	if(idx[r][c] >0 || pic[r][c] != '@') return ;
	idx[r][c] = id;
	for (int dr = -1;dr <= 1;dr++)
	{
		for (int dc = -1;dc <= 1;dc++)
		{
			if(dr != 0 || dc != 0)
				dfs(r+dr,c+dc,id);
		}
	}
}

int main()
{
	int i,j,cnt;
	while (cin>>m>>n,m&&n)
	{
		for (i=0;i<m;i++)
		{
			cin>>pic[i];
		}
		cnt = 0;
		memset(idx,0,sizeof(idx));
        for (i=0;i<m;i++)
        {
			for (j=0;j<n;j++)
			{
               if(idx[i][j]==0 && pic[i][j] == '@')
				   dfs(i,j,++cnt);
			}
        }
		cout<<cnt<<endl;
	}
	return 0;
}

这种方法当数据量很大时,可能会有栈溢出

DFS  2:栈

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stack>
using namespace std;

int m,n,idx[105][105];
char pic[105][105];
struct Node {int x;int y;};
stack<Node> st;

void dfs(int r,int c)
{
//     if (r<0 || r>=m || c<0 || c>= n)   return ;
// 	if(idx[r][c] >0 || pic[r][c] != '@') return ;
	while(!st.empty()) st.pop();
	Node temp;
	temp.x = r;
	temp.y = c;
	st.push(temp);
	idx[r][c] = 1;
	while (!st.empty())
	{

	temp = st.top();
    st.pop();
	for (int dr = -1;dr <= 1;dr++)
	{
		for (int dc = -1;dc <= 1;dc++)
		{
			int drr = dr+temp.x;
			int dcc = dc+temp.y;
			if((dr != 0 || dc != 0) && drr>=0 && drr<m && dcc>=0 && dcc<n  && pic[drr][dcc] == '@' && !idx[drr][dcc])
			//	dfs(r+dr,c+dc,id);
			{
			    Node t;
				idx[drr][dcc] =1;
				t.x = drr;
				t.y = dcc;
				st.push(t);
			}
		}
	}
	}
}

int main()
{
	int i,j,cnt;
	while (cin>>m>>n,m&&n)
	{
		for (i=0;i<m;i++)
		{
			cin>>pic[i];
		}
		cnt = 0;
		memset(idx,0,sizeof(idx));
        for (i=0;i<m;i++)
        {
			for (j=0;j<n;j++)
			{
               if(idx[i][j]==0 && pic[i][j] == '@')
			   {
				   cnt++;
				   dfs(i,j);
			   }
			}
        }
		cout<<cnt<<endl;
	}
	return 0;
}

BFS:(队列实现)可用STL  也可以数组

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
using namespace std;

int m,n,idx[105][105];
char pic[105][105];
struct Node {int x;int y;};
//stack<Node> st;
//queue<Node> st;
Node que[105];

void dfs(int r,int c)
{
//     if (r<0 || r>=m || c<0 || c>= n)   return ;
// 	if(idx[r][c] >0 || pic[r][c] != '@') return ;
	//while(!st.empty()) st.pop();
	que[0].x = r;
	que[0].y = c;
	idx[r][c] = 1;
	int front=0;
	int rear=1;
	while (front < rear)
	{
       Node temp=que[front++];
	for (int dr = -1;dr <= 1;dr++)
	{
		for (int dc = -1;dc <= 1;dc++)
		{
			int drr = dr+temp.x;
			int dcc = dc+temp.y;
			if((dr != 0 || dc != 0) && drr>=0 && drr<m && dcc>=0 && dcc<n  && pic[drr][dcc] == '@' && !idx[drr][dcc])
			{
				idx[drr][dcc] =1;
				que[rear].x = drr;
				que[rear].y = dcc;
				rear++;
			}
		}
	}
	}
}

int main()
{
	int i,j,cnt;
	while (cin>>m>>n,m&&n)
	{
		for (i=0;i<m;i++)
		{
			cin>>pic[i];
		}
		cnt = 0;
		memset(idx,0,sizeof(idx));
        for (i=0;i<m;i++)
        {
			for (j=0;j<n;j++)
			{
               if(idx[i][j]==0 && pic[i][j] == '@')
			   {
				   cnt++;
				   dfs(i,j);
			   }
			}
        }
		cout<<cnt<<endl;
	}
	return 0;
}
时间: 2024-10-29 00:08:03

UVA 572 搜索 初识BFS DFS的相关文章

UVA 572 -- Oil Deposits(DFS求连通块+种子填充算法)

UVA 572 -- Oil Deposits(DFS求连通块) 图也有DFS和BFS遍历,由于DFS更好写,所以一般用DFS寻找连通块. 下述代码用一个二重循环来找到当前格子的相邻8个格子,也可用常量数组或者写8条DFS调用. 下述算法是:种子填充(floodfill) 两种连通区域 四连通区域:从区域内一点出发,可通过上.下.左.右四个方向的移动组合,在不越出区域的前提下,能到达区域内的任意像素 八连通区域:从区域内每一像素出发,可通过八个方向,即上.下.左.右.左上.右上.左下.右下移动的

UVa 572 Oil Deposits (Floodfill &amp;&amp; DFS)

题意 :输入一个m行n列的字符矩阵,统计字符"@"组成多少个八连块.如果两个字符"@"所在的格子相邻(横竖以及对角方向),就是说它们属于同一个八连块. 分析 :可以考虑种子填充深搜的方法.两重for循环枚举所有的点,然后只要是@点且还没被染色过则从这个点出发到达相邻的点染成同样的色(这里的颜色可以用不同的数字来表示),然后每一块@的联通块都能通过这种方式求出来,详情可以参考Wiki百科的动画帮助理解=>http://en.widipedia.org/wiki/

UVa 572 - Oil Deposits 【DFS】联通块问题

题目链接 题目大意: 求图中@连通块的个数,只要两个@相邻就算它们是连通的(斜方向的也算相邻) #include <stdio.h> #include <string.h> char map[110][110]; int vis[110][110]; int n, m, ans; int dir[8][2] = { {0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1} }; void dfs(int a,int b) { int

UVA - 572 - Oil Deposits (图的DFS!)

UVA - 572 Oil Deposits Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description  Oil Deposits  The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works

UVa 572 Oil Deposits(DFS)

 Oil Deposits  The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots.

搜索分析(DFS、BFS、递归、记忆化搜索)

搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2)递归(从中间向两边) 1 //递归一定要写成记忆化递归 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool vis[11]; 5 int count1=0; 6 7 void search(int n){ 8 count1++; 9

UVA 572 Oil Deposits油田(DFS求连通块)

UVA 572     DFS(floodfill)  用DFS求连通块 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M

UVA 572 dfs求连通块

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyze

hdu 4771 Stealing Harry Potter&#39;s Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: 目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离: 解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点  j 的距离: 然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的: AC代码: 1 #include<iostream>