关于【广度优先搜索】

题目1456:胜利大逃亡

题目描述:

Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会.魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从一个坐标走到相邻的六个坐标中的其中一个.现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1.

输入:

输入数据的第一行是一个正整数K,表明测试数据的数量.每组测试数据的第一行是四个正整数A,B,C和T(1<=A,B,C<=50,1<=T<=1000),它们分别代表城堡的大小和魔王回来的时间.然后是A块输入数据(先是第0块,然后是第1块,第2块......),每块输入数据有B行,每行有C个正整数,代表迷宫的布局,其中0代表路,1代表墙。

输出:

对于每组测试数据,如果Ignatius能够在魔王回来前离开城堡,那么请输出他最少需要多少分钟,否则输出-1.

样例输入:
1
3 3 4 20
0 1 1 1
0 0 1 1
0 1 1 1
1 1 1 1
1 0 0 1
0 1 1 1
0 0 0 0
0 1 1 0
0 1 1 0
样例输出:
11

代码如下:
#include <iostream>
#include <stdio.h>
#include <queue>

using namespace std;

/*所谓广度优先搜索,即在遍历解答树时使每次状态转移时扩展出尽可能多
的新状态,并且按照各个状态出现的先后顺序依次扩展它们。但是,这样所
需查找的状态是非常多,最坏情况下,因为每个结点都能扩展出6个新结点,
那么仅走10步,其状态数就会达到6^10,需要大量的时间才能依次遍历完这
些状态,所以我们必须采用相应的措施来制约状态的无限扩展,这个方法就
是剪枝*/

/*在起点走向终点的最短路径上,到达任意一个中间结点所用的时间都是起
点到达这个结点的最短时间,那么我们所要查找的答案比不可能由该状态进
行若干次扩展后得到*/

/*例如:当我们第一次查找到包含点(x,y,z)的坐标状态后,其后查找到的
任意包含该坐标的状态都不必扩展*/

bool mark[50][50][50];  //标记数组
int maze[50][50][50];   //保存立方体信息

struct N{
    int x;
    int y;
    int z;
    int t;
};

queue<N> Q;            //队列,队列中的元素为状态
int go[][3]={          //坐标变换数组,由坐标(x,y,z)扩展得到的新坐标均可
        {1,0,0},       //通过(x+go[i][0],y+go[i][1],z+go[i][2])得到
        {-1,0,0},
        {0,1,0},
        {0,-1,0},
        {0,0,1},
        {0,0,-1}
        };

int BFS(int a,int b,int c){    //广度优先搜索,返回其最少耗时
    while(Q.empty()==false){   //当队列中仍有元素可以扩展时循环
        N now=Q.front();       //得到队头状态
        Q.pop();               //从队列中弹出队头状态
        for(int i=0;i<6;i++){  //依次扩展其6个相邻结点
            int nx=now.x+go[i][0];
            int ny=now.y+go[i][1];
            int nz=now.z+go[i][2];
            if(nx<0||nx>=a||ny<0||ny>=b||nz<0||nz>=c)  //若新坐标在立方体外,则丢弃该坐标
                continue;
            if(maze[nx][ny][nz]==1)     //若该位置为墙,则丢弃该坐标
                continue;
            if(mark[nx][ny][nz]==true)  //若包含该坐标的状态已经被得到过,则丢弃该状态
                continue;
            N temp;                     //新的状态
            temp.x=nx;
            temp.y=ny;
            temp.z=nz;                  //新状态包含的坐标
            temp.t=now.t+1;             //新状态的耗时
            Q.push(temp);               //将新状态加入到队列
            mark[nx][ny][nz]=true;      //标记该坐标
            if(nx==a-1&&ny==b-1&&nz==c-1)
                return temp.t;
        }
    }
    return -1;
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int a,b,c,t;
        scanf("%d%d%d%d",&a,&b,&c,&t);     //输入
        for(int i=0;i<a;i++){
            for(int j=0;j<b;j++){
                for(int k=0;k<c;k++){
                    scanf("%d",&maze[i][j][k]);      //输入立方体信息
                    mark[i][j][k]=false;             //初始化标记数组
                }
            }
        }
        while(Q.empty()==false)          //清空队列
            Q.pop();
        mark[0][0][0]=true;              //标记起点
        N temp;
        temp.x=temp.y=temp.z=temp.t=0;   //初始状态
        Q.push(temp);                    //将初始状态放入队列
        int rec=BFS(a,b,c);              //广度优先搜索
        if(rec<=t)
            printf("%d\n",rec);          //若所需时间符合条件,则输出
        else
            printf("-1\n");              //否则输出-1
    }
    return 0;
}

/**************************************************************
    Problem: 1456
    User: lcyvino
    Language: C++
    Result: Accepted
    Time:30 ms
    Memory:2132 kb
****************************************************************/

时间: 2024-08-06 16:05:51

关于【广度优先搜索】的相关文章

无向图的深度优先与广度优先搜索代码实现

图采用了邻接表的形式储存. 带不带权都无所谓的 深度优先搜索 Depth First Search 道理和树的先序遍历差不多,把将要访问的点入栈,然后从栈里取点进行访问. 由于这只是类中的一个成员函数,有些被调用的函数的具体代码将会在文章最后补上 ,但是函数功能看注释就好了 1 //深度优先 2 void GraphAdjacencyListWeight::DFSAdvanced(int StartVertex) { 3 int *visited = new int[VertexNumber];

SDUT 2141 【TEST】数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) Input 输入第一行为整数n(0< n <100),表示数据的组数.对于每组数据,第一行是三个整数k,m,t(0<

数据结构实验之图论二:基于邻接表的广度优先搜索遍历

数据结构实验之图论二:基于邻接表的广度优先搜索遍历 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数. 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,

图算法系列-深度优先搜索与广度优先搜索

2.深度优先搜索 为了访问一个顶点,我们将它标记为已经访问过,然后递归的访问所有与子邻接的并且尚未标记的顶点,这就是深度优先搜索(DFS),DFS常用于解决路径问题. 比如下面的连通图,我们从顶点0开始对图进行探索 下面这个图显示了DFS处理时的递归调用树. DFS可以解决的问题:1)环检测:一个图中有环吗?该图是森林吗?2)简单路径:给定两个顶点,是否存在一条连接他们的路径3)简单连通性:无论何时使用DFS,都可以在线性时间内确定一个图是否连通4)顶点搜索:在给定顶点所在的同一个连通分量中有多

图的遍历(深度优先与广度优先搜索两种方案)

1.图的遍历--深度优先搜索 import java.util.Scanner ; public class Map{ static int n ; static int m ; static int[] book ; static int[][] e ; public static void mapDfs(int cur){ //深度优先搜索思想核心: System.out.print(cur + " ") ; for (int i=1;i<=n;i++) { if (e[cu

矩阵图中的广度优先搜索

经常会有类似的题目,如迷宫问题,在一个矩阵图中给定出发点和目标点,每次只能上下左右移动,求到目标点的最短走法,或者说是一共有多少种走法. 思路其实很简单,深搜.广搜.相对比较而言,广度优先搜索更加实用于求最短的走法(步数) 在矩阵图中的广搜需要注意一下几点. 1.确定每步的走法:不同题的走法可能不同,每次搜索时将走法保存在数组中. 2.确定初始状态 往往注意刚开始得起点(i,j)必须把MAP(i,j)改变为 -1(或者其他的),栈中第一个元素即为初始状态 3.保存状态.这点很重要.需要用数组或者

地牢逃脱(BFS(广度优先搜索))

题目描述 给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上.地牢的出口可能在任意某个可以通行的位置上.牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢. 输入描述: 每个输入包含 1 个测试用例.每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 50),表示

图的广度优先搜索(BFS)

把以前写过的图的广度优先搜索分享给大家(C语言版) 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define MAX_VERTEX_NUM 20 4 #define MAXQSIZE 100 5 #define OK 1 6 typedef char VertexType; 7 typedef int QElemType; 8 9 typedef struct ArcNode//边结点 10 { 11 int adjvex; 12 str

SDUT 2142 【TEST】数据结构实验之图论二:基于邻接表的广度优先搜索遍历

数据结构实验之图论二:基于邻接表的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) Input 输入第一行为整数n(0< n <100),表示数据的组数.对于每组数据,第一行是三个整数k,m,t(0<

图的遍历之 深度优先搜索和广度优先搜索

本章会先对图的深度优先搜索和广度优先搜索进行介绍,然后再给出C/C++/Java的实现. 目录 1. 深度优先搜索的图文介绍 1.1 深度优先搜索介绍 1.2 深度优先搜索图解 2. 广度优先搜索的图文介绍 2.1 广度优先搜索介绍 2.2 广度优先搜索图解 3. 搜索算法的源码 深度优先搜索的图文介绍 1. 深度优先搜索介绍 图的深度优先搜索(Depth First Search),和树的先序遍历比较类似. 它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然