UVA1601-双向广度优先搜索
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std; int w, h, n, s[], t[];
char dataset[][];
int G[][], vis[][][], dist[][][];
int deg[];
int dx[] = {, -, , , };//这里包含了不移动的情形
int dy[] = {, , , -, }; inline int ID(int a, int b, int c)
{
return (a << ) | (b << ) | c;
}//一种看起来屌炸天的数据整合方式 inline bool conflict(int a, int b, int a2, int b2)
{
return ((a2 == b2) || (a == b2 && b == a2));
//前者是两者运动到同一位置,后者是两者同时交换位置
} int bfs()
{
queue<int> q;
q.push(ID(s[], s[], s[]));
dist[s[]][s[]][s[]] = ;//dist初始值是-1,这里的0是做标记
while(!q.empty())
{
int u = q.front(); q.pop();
int a = (u >> ) & 0xff, b = (u >> ) & 0xff, c = u & 0xff;
//一种看起来屌炸天的数据整合方式,记住!!
if(a == t[] && b == t[] && c == t[]) return dist[a][b][c];
//a对应了main中的cnt编号,它并没有直接验证横竖坐标而是验证了其编号
for(int i = ; i < deg[a]; i++)
{//deg[a]是cnt编号为a的字母在该点的所有可行的运动方向的个数,遍历所有可行方向
int a2 = G[a][i];
//cnt编号为a的字母运动结果a2
for(int j = ; j < deg[b]; j++)
{
int b2 = G[b][j];
//cnt编号为b的字母运动结果b2
if(conflict(a, b, a2, b2))continue;
//对于产生的运动冲突,由第二个字母做出变换方向的让步
for(int k = ; k < deg[c]; k++)
{
int c2 = G[c][k];
//cnt编号为c的字母运动结果c2
if(conflict(a, c, a2, c2) || conflict(b, c, b2, c2))continue;
if(dist[a2][b2][c2] == -)
{
dist[a2][b2][c2] = dist[a][b][c] + ;
//这是记录步数
q.push(ID(a2, b2, c2));
}
}
}
}
}
return -;
} int main() {
//freopen("input.txt", "r", stdin);
while(~scanf("%d%d%d\n", &w, &h, &n) && n)
{
for(int i = ; i < h; i++) fgets(dataset[i], , stdin);
//输入图
int cnt = , x[], y[], id[][];
for(int i = ; i < h; i++)
for(int j = ; j < w; j++)
{
if(dataset[i][j] != '#')//对于所有的可行动的位置都由一个cnt编号
{
//s->cnt->x与y 这是一种值得借鉴的对应关系
x[cnt] = i; y[cnt] = j; id[i][j] = cnt;//在图中赋予可行动位置唯一的id
if(islower(dataset[i][j])) s[dataset[i][j] - 'a'] = cnt;
else if(isupper(dataset[i][j])) t[dataset[i][j] - 'A'] = cnt;
cnt++;//所有的坐标均被分配到x与y数组中,cnt是唯一的确认,将两个数据映射成了一个数据!!!
}//记录bfs路径的起点与终点的信息 s数组是起点,t数组是终点,
}
for(int i = ; i < cnt; i++)//对应每一个位置
{
deg[i] = ;
for(int j = ; j < ; j++)//对应不同的方向且考虑了不移动的情形
{
int nx = x[i] + dx[j]; int ny = y[i] + dy[j];
if(dataset[nx][ny] != '#') G[i][deg[i]++] = id[nx][ny];
//G[cnt编号][方向]
}
}
//对于所有的位置的每一个可行的方向都记录下来
if(n <= ) { deg[cnt] = ; G[cnt][] = cnt; s[] = t[] = cnt++; }
if(n <= ) { deg[cnt] = ; G[cnt][] = cnt; s[] = t[] = cnt++; }//这里似乎是控制移动对象个数
memset(dist, -, sizeof(dist));
printf("%d\n", bfs());
}
return ;
}
这不是我的代码,这是一个很好的代码,下面有几个方面值得借鉴学习:
1、数据结构设计十分巧妙,仅仅使用普通的数组建立的结构使得数据的查找与变换十分快捷方便
2、利用这个代码中的映射结构,提前准备好每个点可行的方向,这个可以用于平时的bfs或dfs中
UVA1601-双向广度优先搜索的更多相关文章
- BFS(三):双向广度优先搜索
所谓双向广度搜索指的是搜索沿两个方向同时进行:(1)正向搜索:从初始结点向目标结点方向搜索:(2)逆向搜索:从目标结点向初始结点方向搜索:当两个方向的搜索生成同一子结点时终止此搜索过程. 广度双向搜索 ...
- 51nod 1444:破坏道路 广度优先搜索
1444 破坏道路 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 取消关注 在某一个国家,那儿有n个城市,他们通过 ...
- 图的广度优先搜索(BFS)
把以前写过的图的广度优先搜索分享给大家(C语言版) #include<stdio.h> #include<stdlib.h> #define MAX_VERTEX_NUM 20 ...
- 广度优先搜索(BFS)
定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...
- 总结A*,Dijkstra,广度优先搜索,深度优先搜索的复杂度比较
广度优先搜索(BFS) 1.将头结点放入队列Q中 2.while Q!=空 u出队 遍历u的邻接表中的每个节点v 将v插入队列中 当使用无向图的邻接表时,复杂度为O(V^2) 当使用有向图的邻接表时, ...
- ACM题目————图的广度优先搜索
题目描述 图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接 点的邻接点.如此进行下去,直到所有的结点都访问为止.在该题中,假定所有的结 ...
- SDUT 2141 【TEST】数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历
数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...
- HDU 1312 Red and Black DFS(深度优先搜索) 和 BFS(广度优先搜索)
Red and Black Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- HDU 1241 Oil Deposits DFS(深度优先搜索) 和 BFS(广度优先搜索)
Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...
- HDU 1242 Rescue (BFS(广度优先搜索))
Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
随机推荐
- 在 Vs2013中查看类的内部布局
第一步:在Visual Studio中配置命令行环境(Command Prompt) 来自:https://blog.csdn.net/u013553529/article/details/77417 ...
- 动手学习Pytorch(6)--卷积神经网络基础
卷积神经网络基础 本节我们介绍卷积神经网络的基础概念,主要是卷积层和池化层,并解释填充.步幅.输入通道和输出通道的含义. 二维卷积层 本节介绍的是最常见的二维卷积层,常用于处理图像数据. 二维 ...
- 独立磁盘冗余阵列-RAID
一.RAID概述 RAID(Redundant Array of Independent Disks)即独立冗余磁盘阵列 磁盘阵列就是.由很多块廉价磁盘 组成的一个容量巨大的卷组.然后在使用不同级别的 ...
- P3387缩点(tarjan+拓扑排序+线性dp)
题目描述 给定一个 n个点 m 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 输入 ...
- Thingsboard源码安装部署
交流QQ群 如果安装有其他问题,可以到QQ群求助 环境安装 开发环境要求:Jdk 1.8版本Postgresql 9以上Node.jsNpmMaven 3.6以上Git工具Idea开发工具 JDK 下 ...
- 1.【Spring Cloud Alibaba】服务发现-Nacos
一.服务的提供者与服务的消费者 二.服务发现原理 如果用户中心地址发生变化怎么办? 服务的消费者总能找到服务的提供者的这种原理,即服务发现原理. 三.什么是Nacos? Nacos文档地址请查看,引入 ...
- numpy 介绍与使用
一.介绍 中文文档:https://www.numpy.org.cn/ NumPy是Python语言的一个扩展包.支持多维数组与矩阵运算,此外也针对数组运算提供大量的数学函数库.NumPy提供了与Ma ...
- php 安装扩展插件实例-ftp.so
工作记录一下 1.首先进入原始php包安装文件(不是安装后的文件,是下载php安装压缩包,解压后的那个文件)安装包里有个扩展文件夹ext,进入 #cd /home/php-5.3.3/ext/#l ...
- layui table 表头和内容数据不能对齐
个人博客 地址:http://www.wenhaofan.com/article/20181224153019 今天使用layui table方法渲染时出现了个莫名其妙的错误 正常情况table应该是 ...
- [Contract] Solidity 变量类型的默认值
变量的默认值一般都代表 “零值”. 比如 bool 就是 false,uint.int 就是 0,string 就是空字符串. 其它组合的参考 Solidity 判断 mapping 值的存在 Ref ...