ACM_程序设计竞赛:穷举法:BFS(广度优先)

  • 类似于层次遍历
  • 首先访问起始顶点v,
  • v出发,依次访问领接的顶点 w1,w2,...,wi
  • 不后退,一步可以访问一批结点

    //结果:abcdefgh

这里写图片描述

 //算法:
 bool visited[MAX_VERTEX_NUM];//访问标记数组
 void BFSTraverse(Graph G){
 //图G进行广度优先遍历,设访问函数visit()
     for(i=0;i<G.vexnum;++i)
         visited[i]=FALSE
     InitQueue(Q);  //初始化辅助队列
     for(i=0;i<G.vexnum;++i) //从0开始遍历
         if(!visited[i])     //对每个连通分量调用BFS
             BFS(G,i); //vi 未访问,从vi开始BFS
 }

 void  BFS(Graph G, int v){
     visit(v); // 访问初始化顶点v
     visited[v]=TRUE; //对v做标记
     Enqueue(Q,v); //顶点v入队
     while(!isEmpty(Q)){
         DeQueue(Q,v); //顶点v出队列
         for(w=FristNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)) //检查v的所有领接点
             if(!visited[w]) //w是尚未检查的顶点
                 visited(w); //访问顶点
                 visited[w]=TRUE; //标记w
                 EnQueue(Q,w); //顶点w入队列
     }
 }
  • 复杂度
    借助队列工作:空间复杂度:O(|V|)
    领接矩阵:查找每个顶点的时间复杂度是 O(|v|2)
    领接表:查找的时间(O(|E|)),访问的时间O(|v|); 总时间=O(|V|+|E|)

迷宫最短路径

  • 给定一个大小是N*M的迷宫,每一步向领接的上下左右四格的通道移动。请求出从起点到终点所需的最小步数
    限制条件:N,M<=100
* 输入
N=10,M=10
#: 墙壁;.:通道; S:起点 G:终点 
#S########
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

输出:22
  • 算法:
    1. 有近及远的顺序操作
    2. 将访问过的状态标注
    3. d[N][M]数组表示最短距离
#include <stdio.h>  
#include <string.h>  
#include <queue>  
using namespace std;  

struct node  
{  
    int x,y,step;  
};  

char map[105][105];  
int vis[105][105];  
int to[4][2]= {1,0,-1,0,0,1,0,-1};  
int n,m,sx,sy,ex,ey,ans;  

int check(int x,int y)  
{  
    if(x<0 || x>=n || y<0 || y>=m)  
        return 1;  
    if(vis[x][y] || map[x][y]=='#')  
        return 1;  
    return 0;  
}  

void bfs()  
{  
    int i;  
    queue<node> Q;  
    node a,next;  
    a.x = sx;  
    a.y = sy;  
    a.step = 0;  
    vis[a.x][a.y]=1;  
    Q.push(a);  
    while(!Q.empty())  
    {  
        a = Q.front();  
        Q.pop();  
        if(map[a.x][a.y]=='E')  
        {  
            ans = a.step;  
            return ;  
        }  
        for(i = 0; i<4; i++)  
        {  
            next = a;  
            next.x+=to[i][0];  
            next.y+=to[i][1];  
            if(check(next.x,next.y))  
                continue;  
            next.step=a.step+1;  
            vis[next.x][next.y] = 1;  
            Q.push(next);  
        }  
    }  
    ans = -1;  
}  

int main()  
{  
    int t;  
    scanf("%d",&t);  
    while(t--)  
    {  
        scanf("%d%d",&n,&m);  
        int i,j;  
        for(i = 0; i<n; i++)  
            scanf("%s",map[i]);  
        for(i = 0; i<n; i++)  
        {  
            for(j = 0; j<m; j++)  
            {  
                if(map[i][j]=='S')  
                {  
                    sx = i;  
                    sy = j;  
                }  
            }  
        }  
        memset(vis,0,sizeof(vis));  
        bfs();  
        printf("%d\n",ans);  
    }  

    return 0;  
}  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ACM程序设计竞赛基础教程(第2版)》是一本经典的程序设计竞赛教材,旨在帮助学习者掌握ACM程序设计竞赛的基础知识和解题技巧。 该教材以清晰简明的语言详细介绍了ACM竞赛所需的基本知识,包括数据结构、算法设计与分析、动态规划、图论等。同时,它提供了大量的例题和习题,帮助学习者巩固知识,培养解题能力。 与其他类似的教材相比,这本教材具有以下几个特点: 首先,该教材内容全面,不仅介绍了ACM竞赛中常见的基础知识,还涵盖了一些高级内容。通过学习这本教材,学习者能够建立起扎实的程序设计基础,为进一步深入学习和应用打下坚实的基础。 其次,该教材注重实战,提供了大量的例题和习题。这些题目都是经过精心挑选和设计的,能够帮助学习者理解和掌握各种解题技巧。通过反复练习,学习者能够逐渐提高自己的编程水平和解题能力。 最后,该教材配有详细的讲解和解答,帮助学习者更好地理解和掌握知识点。无论是初学者还是有一定基础的学习者,都可以根据自己的情况选择性地学习和提升。 《ACM程序设计竞赛基础教程(第2版)》是一本值得推荐的优秀教材,它不仅适用于参加ACM竞赛的学生,也适用于对算法和程序设计感兴趣的人。通过学习这本教材,学习者能够提高自己的编程能力,锻炼解决问题的思维方式,为将来的学习和工作打下良好的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值