#include<cstdio>
#include<map>
#include<vector>
#include<stack>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdlib>
#define PI acos(-1.0)
using namespace std;
typedef long long ll;
const ll mood=1e9+;
const double eps=1e-;
const int N=1e4+;
const int MAXN=;
struct node{
string password;
int cnt;
}now,tmp;
string beg,end;
map<string,int>back_vis;
map<string,int>vis;
queue<struct node>q;
queue<struct node>back_q;
int back_bfs(int n)//反向BFS,每次只搜一层,即第n层
{
while(back_q.front().cnt<=n)
{
now=back_q.front();
back_q.pop();
for(int i=;i<;i++)
{ //各个位-1\
tmp=now;
if(tmp.password[i]!='')
tmp.password[i]--;
else tmp.password[i]='';
if(vis.find(tmp.password)!=vis.end())//判断是否在正向队列中找到
return tmp.cnt++vis[tmp.password];
if(back_vis.find(tmp.password)==back_vis.end())
{
tmp.cnt++;
back_q.push(tmp);
back_vis[tmp.password]=tmp.cnt;
} //各个位+1
tmp=now;
if(tmp.password[i]!='') tmp.password[i]++;
else tmp.password[i]='';
if(vis.find(tmp.password)!=vis.end())//判断是否在正向队列中找到
return tmp.cnt++vis[tmp.password];
if(back_vis.find(tmp.password)==back_vis.end())
{
tmp.cnt++;
back_q.push(tmp);
back_vis[tmp.password]=tmp.cnt;
}
}
for(int i=;i<;i++)
{
tmp=now;
swap(tmp.password[i],tmp.password[i+]);
if(vis.find(tmp.password)!=vis.end())//判断是否在正向队列中找到 、
return tmp.cnt++vis[tmp.password];
if(back_vis.find(tmp.password)==back_vis.end())
{ tmp.cnt++; back_q.push(tmp); back_vis[tmp.password]=tmp.cnt; }
}
}
return -;
}
int bfs()
{
while(!q.empty())
q.pop();//清空正向BFS的队列
now.password=beg;
now.cnt=;
q.push(now);
vis[beg]=;
while(!q.empty())
{
int n=q.front().cnt;
while(q.front().cnt<=n)
{
now=q.front(); q.pop();
for(int i=;i<;i++)
{ //各个位-1
tmp=now;
if(tmp.password[i]!='')
tmp.password[i]--;
else tmp.password[i]='';
if(back_vis.find(tmp.password)!=back_vis.end())//判断是否在反向队列中找到
return tmp.cnt++back_vis[tmp.password];
if(vis.find(tmp.password)==vis.end())
{ tmp.cnt++; q.push(tmp); vis[tmp.password]=tmp.cnt; } //各个位+1
tmp=now;
if(tmp.password[i]!='') tmp.password[i]++;
else tmp.password[i]='';
if(back_vis.find(tmp.password)!=back_vis.end())//判断是否在反向队列中找到
return tmp.cnt++back_vis[tmp.password];
if(vis.find(tmp.password)==vis.end())
{ tmp.cnt++; q.push(tmp); vis[tmp.password]=tmp.cnt; }
}
for(int i=;i<;i++)
{
tmp=now;
swap(tmp.password[i],tmp.password[i+]);
if(back_vis.find(tmp.password)!=back_vis.end())//判断是否在反向队列中找到
return tmp.cnt++back_vis[tmp.password];
if(vis.find(tmp.password)==vis.end()) {
tmp.cnt++; q.push(tmp);
vis[tmp.password]=tmp.cnt;
}
}
}
int ret=back_bfs(now.cnt);
if(ret!=-)
return ret;
}
}
int main(){
int t;
while(cin>>t)
{
while(t--)
{
cin>>beg;
cin>>end;
vis.clear();//清空map
back_vis.clear();//清空map
while(!back_q.empty())
back_q.pop();//清空反向BFS的队列
now.password=end;
now.cnt=;
back_q.push(now);
back_vis[end]=;//将反向BFS的起始点入队列标记
int ret=bfs();
cout<<ret<<endl;
}
}
return ;
}

还没懂

HDOJ1195 双向BFS //单向也可以过 没想清的更多相关文章

  1. UVA - 1601 The Morning after Halloween (双向BFS&单向BFS)

    题目: w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...

  2. Word Ladder(双向BFS)

    2018-10-02 23:46:38 问题描述: 问题求解: 显然是个解空间遍历问题,每次修改其中一位,由于步长是1,所以可以使用BFS进行解空间的遍历.

  3. POJ1915Knight Moves(单向BFS + 双向BFS)

    题目链接 单向bfs就是水题 #include <iostream> #include <cstring> #include <cstdio> #include & ...

  4. POJ 1915-Knight Moves (单向BFS &amp;&amp; 双向BFS 比)

    主题链接:Knight Moves 题意:8个方向的 马跳式走法 ,已知起点 和终点,求最短路 研究了一下双向BFS,不是非常难,和普通的BFS一样.双向BFS只是是从 起点和终点同一时候開始搜索,可 ...

  5. 双向BFS和启发式搜索的应用

    题目链接 P5507 机关 题意简述   有12个旋钮,每个旋钮开始时处于状态 \(1\) ~ \(4\) ,每次操作可以往规定方向转动一个旋钮 (\(1\Rightarrow2\Rightarrow ...

  6. [转] 搜索之双向BFS

    转自:http://www.cppblog.com/Yuan/archive/2011/02/23/140553.aspx 如果目标也已知的话,用双向BFS能很大程度上提高速度. 单向时,是 b^le ...

  7. 双向BFS

    转自“Yuan” 如果目标也已知的话,用双向BFS能很大提高速度 单向时,是 b^len的扩展. 双向的话,2*b^(len/2)  快了很多,特别是分支因子b较大时 至于实现上,网上有些做法是用两个 ...

  8. HDU 3085 Nightmare Ⅱ (双向BFS)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  9. POJ 3126 Prime Path 解题报告(BFS & 双向BFS)

    题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...

随机推荐

  1. Flutter实战视频-移动电商-50.持久化_shared_preferences

    50.持久化_shared_preferences 当app关掉了.再进去的时候 ,购物车的内容还是存在. sqflite提供这个来操作SQLite数据库 flutter提供三种持久化的工具 今天要学 ...

  2. 使用命令把类打成jar包

    测试用类 public class Hello { public static void main(String[] args) { System.out.println("hello wo ...

  3. HDU5880【AC自动机】

    题意: 给出n个字符串,再给出一个字符串,把之前出现过的字符串全部变成* 思路: AC自动机,Trie树上存的值是一个字符串的长度,也就是往前的长度,然后倒着处理一遍. 感想: 第三题AC自动机,本来 ...

  4. Unity3D中常用的数据结构总结与分

    阅读目录 1.几种常见的数据结构 2.几种常见数据结构的使用情景 来到周末,小匹夫终于有精力和时间来更新下博客了.前段时间小匹夫读过一份代码,对其中各种数据结构灵活的使用赞不绝口,同时也大大激发了小匹 ...

  5. springMVC常用传参总结

    本文介绍了springMVC常用的传参方式和一些注意的事项,页面表单主要以ajax的形式提交. 本帅是个菜鸡,水平有限,若有什么讲得不对或有补充的地方欢迎各位提意见. 一.传递String类型   1 ...

  6. 洛谷P4869 albus就是要第一个出场(线性基)

    传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 线性基居然有这性质我还不知道orz 假设$n$个数的线性基中有$k$个数,那么显然共有$2^k$个不同的异或和,而其中每一个异或和的出现次数都是$2 ...

  7. VRTK3.3.0-004传送

    直线传送: 一.无高度变换传送(VRTK_BasicTeleport) 1丶继续在VRScripts下创建空物体PlayArea,用来挂在传送相关脚本:创建Plane作为传送地面 2丶在PlayAre ...

  8. 自己写一个轻量的JqueryGrid组件

    接触mvc不久,突然没有了viewstate和服务端控件处处都觉得不顺手,很多在webform时不必要考虑的问题都出现在眼前,这其中分页时查询条件保持的问题又是最让我头疼的事情,权衡再三,决定用aja ...

  9. 080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II

    “删除重复项目” 的进阶:如果重复最多被允许两次,又该怎么办呢?例如:给定排序数列 nums = [1,1,1,2,2,3]你的函数应该返回长度为 5,nums 的前五个元素是 1, 1, 2, 2 ...

  10. ASP.NET Core MVC/WebAPi 模型绑定

    public class Person { public string Name { get; set; } public string Address { get; set; } public in ...