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 ...
随机推荐
- java代码之美(16) ---Java8 Optional
Java8 Optional 一句话介绍Optional类:使用JDK8的Optional类来防止NullPointerException(空指针异常)问题. 一.前言 在我们开放过程中,碰到的异常中 ...
- JMeter接口测试-接口签名校验
前言 很多HTTP接口在传参时,需要先对接口的参数进行数据签名加密 如pinter项目的中的签名接口 http://localhost:8080/pinter/com/userInfo 参数为: {& ...
- .NET Core之单元测试(二):使用内存数据库处理单元测试中的数据库依赖
目录 定义一个待测试API 测试用例 为减少篇幅,隐藏了SampleEntity和SqliteDbContext 定义一个待测试API 如下,我们定义了一个名为Sample的API,其中有一个外部依赖 ...
- VFP的数据策略:基础篇
VFP的数据策略:基础篇 概述 在VFP应用程序中,有很多方法可以访问非VFP数据(如SQL Server):远程视图.SQ LPassthrough.ADO.XML……本文件将审查不同机制的利弊,并 ...
- Linux的那些事-系统启动(增加开机启动项)
1 /etc/init.d 2 /etc/inittab 3 /etc/rc.d/init.d 1. /etc/init.d 是一般开机的启动服务存放在这个目录下,至于实现机制,其实 ...
- JVM源码分析之临门一脚的OutOfMemoryError完全解读
概述 OutOfMemoryError,说的是java.lang.OutOfMemoryError,是JDK里自带的异常,顾名思义,说的就是内存溢出,当我们的系统内存严重不足的时候就会抛出这个异常(P ...
- Keras深度学习框架之损失函数
一.损失函数的使用 损失函数[也称目标函数或优化评分函数]是编译模型时所需的两个参数之一. model.compile(loss='mean_squared_error', optimizer='sg ...
- Aliyun搭建svn服务器外网访问报错权限配置失败错误
搭建完后所有的配置如下 [root@iZuf655czz7lmtn8v15tsjZ conf]# pwd /home/SVN/conf [root@iZuf655czz7lmtn8v15tsjZ co ...
- Swift 枚举-从汇编角度看枚举内存结构
一.基本使用 先看枚举的几种使用(暂不要问,看看是否都能看懂,待会会逐一讲解) 1.操作一 简单使用 //第一种方式 enum Direction { case east case west case ...
- 【HDU - 1176 】免费馅饼 (逆dp)
免费馅饼 Descriptions: 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁 ...