BFS经典模板

代码

#include <stdio.h>

#define SIZE 51
struct node
{
    int x;//横坐标
    int y;//纵坐标
    int f;//父亲在队列中得编号
    int s;//步数
};

int main()
{
    struct node que[SIZE*SIZE+1];//保存结点队列

    int data[SIZE][SIZE] = {0};
    int book[SIZE][SIZE] = {0};

    //定义一个用于表示走的方向的数组
    int next[4][2] = {
        {0,1},//向右
        {1,0},//向下
        {0,-1},//向左
        {-1,0},//向上
    };

    int head,tail;

    int i,j,k,n,m,startx,starty,endx,endy,tx,ty,flag;

    //读取矩阵数据
    scanf("%d %d",&n, &m);
    for (i=1; i<=n; i++) {
        for (j=1; j<=m; j++) {
            scanf("%d",&data[i][j]);
        }
    }

    //读取起始点,终点
    scanf("%d %d %d %d", &startx, &starty, &endx, &endy);

    //队列初始化
    head = 1;
    tail = 1;

    //往队列插入起始坐标信息
    que[tail].x = startx;
    que[tail].y = starty;
    que[tail].f = 0;
    que[tail].s = 0;
    tail++;

    book[startx][starty] = 1;

    flag = 0;//用来标记是否到达目标点,0:未到达 1:到达

    //当队列不为空得时候循环
    while (head < tail) {
        //枚举4个方向
        for(k=0;k<4;k++)
        {
            //计算下一个坐标点
            tx = que[tail].x + next[k][0];
            ty = que[tail].y + next[k][1];

            //判断是否越界
            if(tx<1 || tx>n || ty<1 || ty>m)
                continue;

            //判断数据是否有效,或者该结点是否已经在路径中
            if (data[tx][ty] == 0 && book[tx][ty]==0) {

                //标记这个点已经走过,并插入新的点到队列中
                book[tx][ty] = 1;
                que[tail].x = tx;
                que[tail].y = ty;
                que[tail].f = head;//因为该点是从head扩展出来的,所以他的父亲是head
                que[tail].s = que[head].s + 1;//步数是父亲的步数+1

                tail++;
            }

            //如果到目标点了,则停止扩展,任务结束,退出循环
            if (tx == endx && ty == endy) {
                flag = 1;
                break;
            }
        }

        if (flag == 1) {
            break;
        }

        head++;//当一个点扩展结束后,head++才能对后面的点再进行扩展
    }

    //打印队列中末尾最后一个点(目标点)的步数
    //注意:tail是指向队列队尾的下一个位置,所以需要-1
    printf("%d",que[tail-1].s);

    return 0;
}
时间: 2024-10-23 16:00:08

BFS经典模板的相关文章

带权并查集(含种类并查集)【经典模板】 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug&#39;s life(简单) ③hihoCoder 1515 : 分数调查

带权并查集: 增加一个 value 值,并且每次合并和查找的时候需要去维护这个 value 例题一 :POJ 1182 食物链(经典) 题目链接:https://vjudge.net/contest/339425#problem/E 带权并查集的解法 定义两个数组fa[ ]和rela[ ],fa用来判断集合关系,rela用来描述其与根节点的关系.因为关系满足传递性,所以可以推导出给出条件下的当前关系,在判断与之前已有关系是否矛盾. 本题的解法巧妙地利用了模运算,rela数组用0表示同类,1表示当

BFS算法模板(python实现)

BFS算法整理(python实现) 广度优先算法(Breadth-First-Search),简称BFS,是一种图形搜索演算算法. 1. 算法的应用场景 2. 算法的模板 2.1 针对树的BFS模板 无需分层遍历 from collections import deque # Definition for a binary tree node. class TreeNode: def __init__(self, x): self.val = x self.left = None self.ri

poj2135最小费用最大流经典模板题

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13509   Accepted: 5125 Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of

CSU 1120 病毒(经典模板例题:最长公共递增子序列)

1120: 病毒 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 390  Solved: 153[Submit][Status][Web Board] Description 你有一个日志文件,里面记录着各种系统事件的详细信息.自然的,事件的时间戳按照严格递增顺序排列(不会有两个事件在完全相同的时刻发生). 遗憾的是,你的系统被病毒感染了,日志文件中混入了病毒生成的随机伪事件(但真实事件的相对顺序保持不变).备份的日志文件也被感染了,但由于病毒采用

SDUT OJ 图练习-BFS-从起点到目标点的最短步数 (vector二维数组模拟邻接表+bfs , *【模板】 )

图练习-BFS-从起点到目标点的最短步数 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 在古老的魔兽传说中,有两个军团,一个叫天灾,一个叫近卫.在他们所在的地域,有n个隘口,编号为1..n,某些隘口之间是有通道连接的.其中近卫军团在1号隘口,天灾军团在n号隘口.某一天,天灾军团的领袖巫妖王决定派兵攻打近卫军团,天灾军团的部队如此庞大,甚至可以填江过河.但是巫妖王不想付出不必要的代价,他想知道在不修建任何通道的前提下,部队是否

HDU 1312 (BFS搜索模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1312 题目大意:问迷宫中有多少个点被访问. 解题思路: DFS肯定能水过去的.这里就拍了一下BFS. 然后发现自己BFS访问标记有问题,导致某些点被重复访问了. 赶紧改了一下. #include "cstdio" #include "queue" #include "string" #include "cstring" #inc

BFS DFS 模板

/* 该 DFS 框架以 2D 坐标范围为例,来体现 DFS 算法的实现思想. */ #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; const int maxn=100; bool vst[maxn][maxn]; //访问标记 int map[maxn][maxn]; //坐标范围 int dir[4][2]= {0,1,0,-1,1,0,-1,0}; // 方向向量

Acwing 154 滑动窗口(单调队列)经典模板

给定一个大小为n≤106n≤106的数组. 有一个大小为k的滑动窗口,它从数组的最左边移动到最右边. 您只能在窗口中看到k个数字. 每次滑动窗口向右移动一个位置. 以下是一个例子: 该数组为[1 3 -1 -3 5 3 6 7],k为3. 窗口位置 最小值 最大值 [1 3 -1] -3 5 3 6 7 -1 3 1 [3 -1 -3] 5 3 6 7 -3 3 1 3 [-1 -3 5] 3 6 7 -3 5 1 3 -1 [-3 5 3] 6 7 -3 5 1 3 -1 -3 [5 3 6]

poj2251Dungeon Master(bfs模板题)

题目链接:http://poj.org/problem?id=2251 可以说是bfs的模板题了. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<queue> 5 using namespace std; 6 char pic[32][32][32]; 7 int vis[32][32][32]; 8 int dir[6][3]={0,0,1,0,0,-1,1,0