题目链接:https://vjudge.net/problem/UVA-10150
转自:http://www.cppblog.com/rakerichard/archive/2010/11/15/133619.html
题意:两个单词能够连接的条件是长度相同并且只有一个字母不同,现在让你输出一条两个单词之间的最短路径。
思路:用dij会超时,而bfs则不会。dij的建边最坏情况是25000 * 25000 * 16。
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <cstring>
#include <iostream>
#include <cmath>
#include <unordered_map>
using namespace std;
const int maxn=26000;
const int inf=0x3f3f3f3f;
int cnt[20];
string word[20][maxn];
queue <int> q;
bool judge(string a,string b)
{
int l=a.length(),dif=0;
for(int i=0; i<l; i++)
{
if(a[i]!=b[i])
dif++;
if(dif>1)
{
return false;
}
}
return true;
}
int main()
{
ios::sync_with_stdio(false);
memset(cnt,0,sizeof(cnt));
int T=0;
string t;
while(getline(cin,t)&&!t.empty())
{
int l=t.length();
cnt[l]++;
word[l][cnt[l]]=t;
}
string a,b;
while(cin>>a>>b)
{
T++;
int la=a.length(),lb=b.length(),pa,pb;
int d[maxn],f[maxn];
bool vis[maxn];
if(la!=lb)
{
if(T>=2)
cout<<endl;
cout<<"No solution."<<endl;
continue;
}
for(pa=1; pa<=cnt[la]; pa++)
{
if(word[la][pa]==a)
break;
}
for(pb=1; pb<=cnt[la]; pb++)
{
if(word[la][pb]==b)
break;
}
if(pa>cnt[la]||pb>cnt[la])
{
if(T>=2)
cout<<endl;
cout<<"No solution."<<endl;
continue;
}
memset(d,-1,sizeof(d));
memset(f,0,sizeof(f));
memset(vis,false,sizeof(vis));
while(!q.empty())
q.pop();
q.push(pa);
d[pa]=0;
f[pa]=0;
vis[pa]=true;
while(!q.empty())
{
int r=q.front();
q.pop();
for(int i=1; i<=cnt[la]; i++)
{
if(!vis[i]&&judge(word[la][r],word[la][i]))
{
q.push(i);
d[i]=d[r]+1;
f[i]=r;
vis[i]=true;
}
}
if(d[pb]!=-1)
break;
}
if(d[pb]==-1)
{
if(T>=2)
cout<<endl;
cout<<"No solution."<<endl;
}
else
{
if(T>=2)
cout<<endl;
int num=0,ans[maxn];
num++;
ans[num]=pb;
while(f[pb])
{
num++;
ans[num]=f[pb];
pb=f[pb];
}
for(int i=num; i>=1; i--)
{
cout<<word[la][ans[i]]<<endl;
}
}
}
return 0;
}