蒜头君被暗黑军团包围在一座岛上,所有通往近卫军团的路都有暗黑军团把手。幸运的是,小岛上有一扇上古之神打造的封印之门,可以通往近卫军团,传闻至今没有人能解除封印。
封印之门上有一串文字,只包含小写字母,有 k 种操作规则,每个规则可以把一个字符变换成另外一个字符。经过任意多次操作以后,最后如果能把封印之门上的文字变换成解开封印之门的文字,封印之门将会开启。
蒜头君战斗力超强,但是不擅计算,请你帮忙蒜头君计算至少需要操作多少次才能解开封印之门。
输入格式
输入第一行一个字符串,长度不大于 1000,只包含小写字母,表示封印之门上的文字。
输入第二行一个字符串,只包含小写字母,保证长度和第一个字符串相等,表示能解开封印之门的文字。
输入第三行一个整数 k(0≤k≤676)。
接下来 k 行,每行输出两个空格隔开的字符 a, b,表示一次操作能把字符 a 变换成字符 b。
输出格式
如果蒜头君能开启封印之门,输出最少的操作次数。否则输出一行 −1-1−1。
样例输入
abcd
dddd
3
a b
b c
c d
样例输出
6
思路:本来是利用map记录字符转换,然后通过循环查找知道两个字符一样。但是呢,超时。。。原来这个求任意两个字符之间的最短路径。用弗洛伊德算法。
原来的代码:
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
using namespace std;
char a[1005];
char b[1005];
int k;
int cnt = 0;
map<char,char> mp;
int main()
{
char ch;
int i = 0;
char p,q;
while(scanf("%c",&ch)&&ch != '\n')
{
a[i++] = ch;
}
//a[i] = '\0';
i = 0;
while(scanf("%c",&ch)&&ch != '\n')
{
b[i++] = ch;
}
cin>>k;
for(int i = 0;i<k;i++)
{
cin>>p>>q;
mp[p] = q;
}
for(int i =0;i<strlen(a);i++)
{
while(a[i]!=b[i])
{
a[i] = mp[a[i]];
cnt++;
}
}
cout<<cnt<<endl;
return 0;
}
floyd()算法的核心只有五句
void Flody()
{
for(int k = 0;k<=n;k++)
for(int i = 0;i<n;i++)
for(int j = 0;j<n;j++)
{
if(m[i][j] > m[i][k]+m[k][j])
m[i][j] = m[i][k]+m[k][j];
}
}
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char a[1005];
char b[1005];
int dis[28][28];
const int inf = 100000000;
int k;
int cnt = 0;
void floyd();
int main()
{
char p,q;
scanf("%s",a);
scanf("%s",b);//总是忘记用%s读入
int len = strlen(a);
cin>>k;
for(int i = 0;i<26;i++)
{
for(int j = 0;j<26;j++)
{
dis[i][j] = inf;
}
dis[i][i] = 0;
}
while(k--)
{
//getchar();
// scanf("%c",&p);
// getchar();//读空格
// scanf("%c",&q);
// getchar();//读回车
// dis[p-'0'][q-'0'] = 1;
char s[3],e[3];
scanf("%s%s",s,e); //%s是遇到空字符停止,而gets取得字符串时,是在遇到EOF(串尾)时停止
if(s[0]!=e[0])
dis[s[0]-'a'][e[0]-'a']=1;
}
floyd();
for(int i = 0;i<len;i++)
{
if(dis[a[i]-'a'][b[i]-'a']>=inf)
{
cout<<-1<<endl;
return 0;
}
else cnt += dis[a[i]-'a'][b[i]-'a'];
}
cout<<cnt<<endl;
return 0;
}
void floyd()
{
for(int m = 0;m<26;m++)
{
for(int i = 0;i<26;i++)
{
for(int j = 0;j<26;j++)
{
if(dis[i][j]>dis[i][m]+dis[m][j])
dis[i][j]=dis[i][m]+dis[m][j];
}
}
}
}