#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-双向广度优先搜索的更多相关文章

  1. BFS(三):双向广度优先搜索

    所谓双向广度搜索指的是搜索沿两个方向同时进行:(1)正向搜索:从初始结点向目标结点方向搜索:(2)逆向搜索:从目标结点向初始结点方向搜索:当两个方向的搜索生成同一子结点时终止此搜索过程. 广度双向搜索 ...

  2. 51nod 1444:破坏道路 广度优先搜索

    1444 破坏道路 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  取消关注 在某一个国家,那儿有n个城市,他们通过 ...

  3. 图的广度优先搜索(BFS)

    把以前写过的图的广度优先搜索分享给大家(C语言版) #include<stdio.h> #include<stdlib.h> #define MAX_VERTEX_NUM 20 ...

  4. 广度优先搜索(BFS)

    定义 维基百科:https://en.wikipedia.org/wiki/Breadth-first_search 给定图G=(V,E)和一个可识别的源结点s,广度优先搜索对图G中的边进行系统性的探 ...

  5. 总结A*,Dijkstra,广度优先搜索,深度优先搜索的复杂度比较

    广度优先搜索(BFS) 1.将头结点放入队列Q中 2.while Q!=空 u出队 遍历u的邻接表中的每个节点v 将v插入队列中 当使用无向图的邻接表时,复杂度为O(V^2) 当使用有向图的邻接表时, ...

  6. ACM题目————图的广度优先搜索

    题目描述 图的广度优先搜索类似于树的按层次遍历,即从某个结点开始,先访问该结点,然后访问该结点的所有邻接点,再依次访问各邻接 点的邻接点.如此进行下去,直到所有的结点都访问为止.在该题中,假定所有的结 ...

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

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem ...

  8. 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 ...

  9. HDU 1241 Oil Deposits DFS(深度优先搜索) 和 BFS(广度优先搜索)

    Oil Deposits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ...

  10. HDU 1242 Rescue (BFS(广度优先搜索))

    Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

随机推荐

  1. 不同宿主的iterator不能进行比较

    int main() { string str1, str2; auto it1 = str1.begin(), it2 = str2.begin(); it1 == it2; ; }

  2. 从Golang中open的实现方式看Golang的语言设计

    Golang有很多优点: 开发高效:(C语言写一个hash查找很麻烦,但是go很简单) 运行高效:(Python的hash查找好写,但比Python高效很多) 很少的系统库依赖:(环境依赖少,一般不依 ...

  3. TCP加速方式

    使用windows scaling TCP Extensions for High Performance, RFC1323,https://www.ietf.org/rfc/rfc1323.txt ...

  4. yum安装logstash 不生效

    问题描述 根据logstash的配置方法写了一个配置文件,并放入/etc/logstash/conf.d/目录下,然后我们运行logstash # service logstash start Log ...

  5. linux硬盘分区、格式化、挂载超详细步骤(fdisk/parted))

  6. css横竖屏适配

    Css做到横竖屏适配:定义两个样式 { @media screen and (orientation: portrait){ Css[竖向定义样式] } @media screen and (orie ...

  7. 用msi安装MySQL时MySQL Server组件不能安装,或安装失败

    我的环境:       MySQL8.0.15,       win10 错误描述:在安装MySQL时,如果MySQL Server组件提示不能安装,错误提示是:VS 2015没有安装或安装失败.原因 ...

  8. 一招教你轻松使用数据可视化BI软件创建旅游消费数据可视化大屏

    灯果数据可视化BI软件是新一代人工智能数据可视化大屏软件,内置丰富的大屏模板,可视化编辑操作,无需任何经验就可以创建属于你自己的大屏.大家可以在他们的官网下载软件.   本文以旅游消费数据可视化大屏为 ...

  9. .net core 3 web api jwt 一直 401

    最近在给客户开发 Azure DevOps Exension, 该扩展中某个功能需要调用使用 .NET Core 3 写的 Web Api. 在拜读了 Authenticating requests ...

  10. C#设计模式学习笔记:(10)外观模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7772184.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲结构型设计模式的第五个模式--外 ...