双向广搜
(题目链接)[https://www.acwing.com/problem/content/192/]
一般用于最小步数模型 每次拓展时 挑选空间比较少的来,拓展时将距离等于队头的一层全部拓展
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <queue>
using namespace std;
const int N=6;
string a[N],b[N];
int n;
int extend(queue<string>&q,unordered_map<string,int>&da,unordered_map<string,int>&db,string a[],string b[])
{
int d=da[q.front()];
while(q.size()&&da[q.front()]==d)//扩展距离都是d的一层
{
auto t=q.front();q.pop();
for(int i=0;i<t.size();i++)
for(int j=0;j<n;j++)
if(t.substr(i,a[j].size())==a[j])//可以变换
{
string st=t.substr(0,i)+b[j]+t.substr(i+a[j].size());
if(db.count(st))return da[t]+1+db[st];//相遇了
if(da.count(st))continue;//已经被扩展过了
da[st]=da[t]+1;
q.push(st);
}
}
return 11;
}
int bfs(string A,string B)
{
if(A==B)return 0;
queue<string>qa,qb;
unordered_map<string,int>da,db;
qa.push(A),da[A]=0;
qb.push(B),db[B]=0;
int step=0;
while(qa.size()&&qb.size())
{
int t;
if(qa.size()<=qb.size())t=extend(qa,da,db,a,b);
else t=extend(qb,db,da,b,a);
if(t<=10)return t;
if(++step==10)return -1;
}
return -1;//不连通
}
void solve()
{
string A,B;
cin>>A>>B;
while(cin>>a[n]>>b[n])n++;
int t=bfs(A,B);
if(t==-1)cout<<"NO ANSWER!"<<endl;
else cout<<t<<endl;
}
int main()
{
cin.tie(0)->ios::sync_with_stdio(0);
solve();
return 0;
}