qbxt里双向BFS的例题……
网上好多题解用的是STL黑科技?
抱着练码力的心态手写了队列+find+replace;
顺便map大法好啊
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<map>
using namespace std;
const int MAXN = 20000 + 60;
struct zt
{
string a,b;
}ch[MAXN];
string a,b,s,t;
int cnt;
string q1[MAXN],q2[MAXN];
int head1,head2,tail1,tail2;
bool same(string x,string y)
{
if(x.length() != y.length())return false;
int len = x.length();
for(int i = 0;i < len;i ++)
{
if(x[i] != y[i])return false;
}
return true;
}
int check(string a,string b,int st)
{
if(b.length() > a.length())return -1;
int len1 = a.length(),len2 = b.length();
for(int i = st;i < len1;i ++)
{
if(a[i] == b[0])
{
bool flag = true;
for(int j = 0;j < len2;j ++)
{
if(a[i + j] != b[j])
{
flag = false;
break;
}
}
if(flag)return i;
}
}
return -1;
}
map <string,bool> used1,used2;
map <string,int> step1,step2;
string re(string a,string b,string c,int pos)
{
string ans;
ans = "";
int pos2 = pos + b.length();
int loc = 0;
while(loc < pos)
{
ans += a[loc];
loc ++;
}
int len = c.length();
for(int i = 0;i < len;i ++)
{
ans += c[i];
loc ++;
}
len = a.length();
for(int i = pos2;i < len;i ++)
{
ans += a[i];
loc ++;
}
return ans;
}
int T,flag;
bool F;
int main()
{
//cin >> T;
cin >> s >> t;
while(cin >> a >> b)
{
ch[++ cnt].a = a;
ch[cnt].b = b;
}
q1[tail1 ++] = s;q2[tail2 ++] = t;
used1[s] = true;
used2[t] = true;
while(!same(q1[tail1 - 1],q2[tail2 - 1]))
{
F = 0;
for(int i = 1;i <= cnt;i ++)
{
for(int j = 0;j < q1[head1].length();j ++)
{
int loc = check(q1[head1],ch[i].a,j);
if(loc != -1)
{
j = loc + 1;
string tmp = re(q1[head1],ch[i].a,ch[i].b,loc);
if(used1[tmp])continue;
F = 1;
used1[tmp] = true;
step1[tmp] = step1[q1[head1]] + 1;
q1[tail1 ++] = tmp;
if(used2[tmp])
{
printf("%d",step1[tmp] + step2[tmp]);
return 0;
}
//cout << flag << tmp << '\n';
}
}
}
flag ^= 1;
for(int i = 1;i <= cnt;i ++)
{
for(int j = 0;j < q2[head2].length();j ++)
{
int loc = check(q2[head2],ch[i].b,j);
if(loc != -1)
{
j = loc + 1;
string tmp = re(q2[head2],ch[i].b,ch[i].a,loc);
if(used2[tmp])continue;
F = 1;
used2[tmp] = true;
step2[tmp] = step2[q2[head2]] + 1;
q2[tail2 ++] = tmp;
if(used1[tmp])
{
printf("%d",step1[tmp] + step2[tmp]);
return 0;
}
//cout << flag << tmp << '\n';
}
}
}
flag ^= 1;
head1 ++;
head2 ++;
if(head1 == tail1 || head2 == tail2)
{
printf("NO ANSWER!\n");
return 0;
}
}
return 0;
}
其实……这是假的双向BFS
感谢wwq大佬指出的bug
按代码的搜索顺序,先扩展点2;再扩展点1
此时搜到相同解,路径长度为4
事实上点1的兄弟节点还可能扩展出其它更优解,如图
路径长度为3
综上,正确写法为先将某队列中同一深度的点扩展完,再扩展另一队列,保证深度严格递增。