DFS BFS

DFS:递归

1  procedure DFS(G,v):
2      label v as discovered
3      for all edges from v to w in G.adjacentEdges(v) do
4          if vertex w is not labeled as discovered then
5              recursively call DFS(G,w)

DFS:堆栈

dfs(node start) 
{
	stack<node> s;
	s.push(start);
	while (s.empty() == false) 
	{
		top = s.top();
		s.pop();
		visited[top]=true;
		check for termination condition (have we reached the node we want to?)
		for each v adjacent to top
			if(!visited[v])
				s.push(v);
	}
}


BFS:队列

void bfs(node start) 
{
	queue<node> s;
	s.push(start);
	while (s.empty() == false) 
	{
		top = s.front();
		s.pop();          
                visited[top]=true;
                check for termination condition (have we reached the node we want to?)
                for each v adjancent to top
                    if(!visited[v])
                        s.push(v);
        }
}

例子:

笨笨熊搬家交通篇

描述:     森林里的苯苯熊要乔迁新喜,上次他已经将物品打包完成,并约了朋友来帮忙。接下来他要选定一个搬家的时间,想了很久,就决定在国庆节进行,因为国庆放假朋友们都有时间啦。但是在森林里,从他现在房子到新豪宅,所经之地有山有水,路途曲折,甚至有些道路是不通的。
    请你和他一起查看指定的地图,看看从笨笨熊现在的房子到新宅之间,道路是否是畅通的呢?
    地图是R行、C列的矩阵,矩阵的每一个格子刚好是一天的行程。
    矩阵由“B”、“-”、“#”、“H”四种字符成员组成,其中:
    B: 代表苯苯熊现在的房子;
    H: 代表笨笨熊新的豪宅;
    -: 代表可以通行的道路;
    #: 代表无法通过的障碍(高山、大河等);
    此外,森林里也有交通规则地:在任务位置,只能向“上、下、左、右”四个方向中的其中一个方向行走。
 
运行时间限制: 无限制
内存限制: 无限制
输入: 4  // R的数值
4  // C的数值,下面是地图。
-##-
B--H
#--#
----
 
输出: Y //代表道路可达

N //代表道路不通
 
样例输入: 1
5
-B-H#
样例输出: Y


#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
#include <functional>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <map>
#include <utility>
#include <sstream>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

const int rr[4]={-1,0,0,1};
const int cc[4]={0,-1,1,0};
int R;
int C;
bool go(vector<vector<char> > &mp,int i,int j)
{
	bool ans=false;
	stack<pair<int,int> > s;
	s.push(make_pair(i,j));
	while(!s.empty())
	{
		int ii=s.top().first;
		int jj=s.top().second;
		s.pop();
		mp[ii][jj]='*';
		for(int i=0;i<4;i++)
		{
			int tr=ii+rr[i];
			int tc=jj+cc[i];
			if(tr>=0 && tc>=0 &&tr<R && tc<C && mp[tr][tc]=='H')
			{
				ans=true;
				return ans;
			}
			if(tr>=0 && tc>=0 &&tr<R && tc<C && mp[tr][tc]=='-')
			{
				mp[tr][tc]='*';
				s.push(make_pair(tr,tc));
			}
		}
	}
	return ans;
}

int main()
{	 
	while(cin>>R>>C)
	{
		vector<vector<char> > mp(R,vector<char>(C));
		int sr,sc,dr,dc;
		for(int i=0;i<R;i++)
		{	
			for(int j=0;j<C;j++)
			{
				cin>>mp[i][j];
				if(mp[i][j]=='B'){sr=i;sc=j;}
				if(mp[i][j]=='H'){dr=i;dc=j;}
			}
		}
		bool ans=go(mp,sr,sc);
		if(ans)cout<<'Y'<<endl;
		else cout<<'N'<<endl;
	}
	return 0;
}


TOJ 1959 POJ 1562 Oil Deposits BFS DFS入门题 C语言:

给出n行m列的矩阵,“@”代表有石油,“*”代表没有,如果含有石油的小块相邻,那么属于同一块油田。相邻包括水平、垂直和斜对角,求油田的数量。

BFS代码

#include<stdio.h>

int m, n;
char grid[105][105];
int x[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
int y[8] = {-1, 0, 1, 1, 1, 0, -1, -1};

struct node
{
    int x, y;    
}Q[10005];

void bfs(int a, int b)
{
    int top = 0, i, j, tx, ty;
    Q[top].x = a;
    Q[top++].y = b;
    grid[a][b] = '*';
    for(i = 0; i < top; i ++)
    {
        for(j = 0; j < 8; j ++)
        {
            tx = Q[i].x + x[j];
            ty = Q[i].y + y[j];
            if(tx >= 0 && ty >= 0 && tx < m && ty < n && grid[tx][ty] == '@')
            {
                grid[tx][ty] = '*';
                Q[top].x = tx;
                Q[top++].y = ty;  
            }    
        }    
    }
}

int main(){
    int i, j, cnt;
    while(scanf("%d%d", &m, &n), m)
    {
        for(i = cnt = 0; i < m; i ++)
        {
            scanf("%s", grid[i]);    
        }    
        for(i = 0; i < m; i ++)
        {
            for(j = 0; j < n; j ++)
            {
                if(grid[i][j] == '@')
                {
                    cnt++ ;
                    bfs(i, j);    
                }       
            }    
        }
        printf("%d\n", cnt);
    }
    return 0;
}


DFS代码

#include<stdio.h>

int m, n;
char grid[105][105];
int x[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
int y[8] = {-1, 0, 1, 1, 1, 0, -1, -1};

void dfs(int a, int b)
{
    int i, tx, ty;
    grid[a][b] = '*';
    for(i = 0; i < 8; i ++)
    {
        tx = a + x[i];
        ty = b + y[i];    
        if(tx >= 0 && ty >= 0 && tx < m && ty < n && grid[tx][ty] == '@')
        {
            dfs(tx, ty);
        } 
    }
}

int main()
{
    int i, j, cnt;
    while(scanf("%d%d", &m, &n), m)
    {
        for(i = cnt = 0; i < m; i ++)
        {
            scanf("%s", grid[i]);    
        }    
        for(i = 0; i < m; i ++)
        {
            for(j = 0; j < n; j ++)
            {
                if(grid[i][j] == '@')
                {
                    cnt++ ;
                    dfs(i, j);    
                }       
            }    
        }
        printf("%d\n", cnt);
    }
    return 0;
}


 

                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值