D-BFS 双向广度优先搜索
从起点和终点同时开始搜索,直到两个搜索的点相交,得到最短路径
Code:
// D-BFS
//by:MuQY
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <string>
using namespace std;
int stmap[10005]; // 标记每一个情况下走了几步
int vis[10005]; // 标记每个情况下有没有被访问过,是正向还是逆向
string s, e;
struct Node
{
int num[4];
int step;
};
queue<Node> q, p; // q从s开始,p从e开始
int get_Num(int c[])
{
int tmp = 0;
for (int i = 0; i < 4; i++)
{
tmp *= 10;
tmp += c[i];
}
return tmp;
}
void bfs()
{
memset(vis, 0, sizeof(vis));
memset(stmap, 0, sizeof(stmap));
Node a, b;
int tmp;
while (!q.empty() || !p.empty())
{
if (!q.empty()){
a = q.front();
q.pop();
for (int i = 0; i < 4; i++){
b = a;
b.num[i] = a.num[i] + 1;//+1
if(b.num[i] == 10){
b.num[i] = 1;
}
tmp = get_Num(b.num);
if(vis[tmp] == 0){//没有出现过
b.step = a.step + 1;
stmap[tmp] = b.step;
vis[tmp] = 1;
q.push(b);
}
else if(vis[tmp] == 2){//有交点
cout << a.step + stmap[tmp] + 1;
return;
}
b.num[i] = a.num[i] - 1; //-1
if(b.num[i] == 0){
b.num[i] = 9;
}
tmp = get_Num(b.num);
if (vis[tmp] == 0)
{ // 没有出现过
b.step = a.step + 1;
stmap[tmp] = b.step;
vis[tmp] = 1;
q.push(b);
}
else if (vis[tmp] == 2)
{ // 有交点
cout << a.step + stmap[tmp] + 1 << endl;
return;
}
}
for (int i = 0; i < 3; i++){//交换相邻数字
b = a;
swap(b.num[i], b.num[i + 1]);
tmp = get_Num(b.num);
if(vis[tmp] == 0){
b.step = a.step + 1;
stmap[tmp] = b.step;
vis[tmp] = 1;
q.push(b);
}
else if(vis[tmp] == 2){
cout << a.step + stmap[tmp] + 1 << endl;
return;
}
}
}
if(!p.empty()){
a = p.front();
p.pop();
for (int i = 0; i < 4; i++)
{
b = a;
b.num[i] = a.num[i] + 1; //+1
if (b.num[i] == 10)
{
b.num[i] = 1;
}
tmp = get_Num(b.num);
if (vis[tmp] == 0)
{ // 没有出现过
b.step = a.step + 1;
stmap[tmp] = b.step;
vis[tmp] = 2;
p.push(b);
}
else if (vis[tmp] == 1)
{ // 有交点
cout << a.step + stmap[tmp] + 1 << endl;
return;
}
b.num[i] = a.num[i] - 1; //-1
if (b.num[i] == 0)
{
b.num[i] = 9;
}
tmp = get_Num(b.num);
if (vis[tmp] == 0)
{ // 没有出现过
b.step = a.step + 1;
stmap[tmp] = b.step;
vis[tmp] = 2;
p.push(b);
}
else if (vis[tmp] == 1)
{ // 有交点
cout << a.step + stmap[tmp] + 1 << endl;
return;
}
}
for (int i = 0; i < 3; i++)
{ // 交换相邻数字
b = a;
swap(b.num[i], b.num[i + 1]);
tmp = get_Num(b.num);
if (vis[tmp] == 0)
{
b.step = a.step + 1;
stmap[tmp] = b.step;
vis[tmp] = 2;
p.push(b);
}
else if (vis[tmp] == 1)
{
cout << a.step + stmap[tmp] + 1 << endl;
return;
}
}
}
}
}
int main()
{
int tcase;
cin >> tcase;
while (tcase--)
{
while(!q.empty()){
q.pop();
}
while(!p.empty()){
p.pop();
}
Node ss, ee;
int s_num, e_num;
memset(stmap, 0, sizeof(stmap));
memset(vis, 0, sizeof(vis));
cin >> s >> e;
for (int i = 0; i < 4; i++)
{
ss.num[i] = s[i] - '0';
ee.num[i] = e[i] - '0';
}
s_num = get_Num(ss.num);
e_num = get_Num(ee.num);
ss.step = 0;
ee.step = 0;
vis[s_num] = 1;
vis[e_num] = 2;
q.push(ss);
p.push(ee);
bfs();
}
return 0;
}