思路:
个人感觉是很巧妙的一题啊,总觉得很熟悉但就是差点意思...
首先分析一下bfs是没戏了,每个字母最多26中变换方法(可以自己变成自己),最长1000,26^1000 ,hhh
感觉这题加深了对Floyd的理解吧,由于是小写字母也就是最多有26个城市,我们可以先不去考虑整个字符串,只看把某个字符变为要求的字符需要几步,然后在遍历整个串求出总共需要的步数即可.我们把每一次操作变换看成是一条权值为1的有向边,就发现这是个多元最短路问题了(其实给定你k次变换操作,就相当于是给你了k条右向边啊。)
#include <bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn = 30; string st,dt; ll mp[30][30],k; int main() { while(cin >> st >> dt >> k) { for(int i = 0;i <= 26;++i) { for(int j = 0;j <= 26;++j) { if(i == j) mp[i][i] = 0; else mp[i][j] = inf; } } for(int i = 1;i <= k;++i) { char s1[5],s2[5]; scanf("%s %s",s1,s2); if(s1[0] == s2[0]) continue; mp[s1[0] - 'a'][s2[0] - 'a'] = 1; } for(int kk = 0;kk < 26;++kk) for(int i = 0;i < 26;++i) for(int j = 0;j < 26;++j) mp[i][j] = min(mp[i][j],mp[i][kk] + mp[kk][j]); bool flag = 1; ll ans = 0; for(int i = 0;i < st.size();++i) { ll dis = mp[st[i] - 'a'][dt[i] - 'a']; if(dis >= inf) { flag = 0; break; } ans += dis; } if(flag) printf("%lld\n",ans); else puts("-1"); } return 0; }