#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. 1.1-1.4 sqoop概述及安装cdh版hadoop

    一.概述 Sqoop是一个在结构化数据和Hadoop之间进行批量数据迁移的工具,结构化数据可以是Mysql.Oracle等RDBMS. Sqoop底层用MapReduce程序实现抽取.转换.加载,Ma ...

  2. lua基本语法

    1.注释--  ;  --[[    ]] 2.控制语句: if ..then ..   elseif..  then..  else.. end while.. do..end repeat ..u ...

  3. 剖析JSONP原理的小例子

    1. 服务器端代码(Node.js) // 导入 http 内置模块 const http = require('http'); // 这个核心模块,能够帮我们解析 URL地址,从而拿到 pathna ...

  4. OpenCV入门指南

    http://blog.csdn.net/morewindows/article/details/8225783/ http://blog.csdn.net/poem_qianmo/article/d ...

  5. HDU3038【种类并查集】

    题意: 给出m组区间[a,b],以及其区间的和,问有矛盾的有几组: 思路: 种类并查集. 主要是几个关系:同类元素的关系,父亲与儿子的关系,不同类元素的关系: 我们可以类似看作一个前缀和,sum[x] ...

  6. IT兄弟连 JavaWeb教程 Servlet会话跟踪 Cookie常用方法

    以下是在Servlet中操作Cookie时可使用的有用的方法列表 ●  public void setDomain(String pattern) 该方法设置cookie适用的域,例如 itxdl.c ...

  7. 使用JRegex抽取网页信息

    当网络爬虫将网页下载到磁盘上以后,需要对这些网页中的内容进行抽取,为索引做准备.一个网页中的数据大部分是HTML标签,索引肯定不会去索引这些标签.也就是说,这种信息是没有用处的信息,需要在抽取过程中过 ...

  8. 2019最好用的自动化测试工具Top 10,果断收藏!

    经常有人在公众号留言或是后台问我,做自动化测试用哪个工具好,或是学哪门编程语言好呢? 这个时候总是无奈的说: 你应该学习Python 或是Java. 你应该掌握Selenium. 又或者你需要学会jm ...

  9. Centos 7.x 搭建 Zabbix3.4

    前提要安装了LAMP(官方推荐环境) LNMP也可以 一.安装.配置Zabbix3.4 1:安装zabbix_RPM包 rpm -i https://repo.zabbix.com/zabbix/3. ...

  10. PAT甲级——1123 Is It a Complete AVL Tree (完全AVL树的判断)

    嫌排版乱的话可以移步我的CSDN:https://blog.csdn.net/weixin_44385565/article/details/89390802 An AVL tree is a sel ...