计蒜客-封印之门(floyd)

封印之门

蒜头君被暗黑军团包围在一座岛上,所有通往近卫军团的路都有暗黑军团把手。幸运的是,小岛上有一扇上古之神打造的封印之门,可以通往近卫军团,传闻至今没有人能解除封印。

封印之门上有一串文字,只包含小写字母,有 kkk 种操作规则,每个规则可以把一个字符变换成另外一个字符。经过任意多次操作以后,最后如果能把封印之门上的文字变换成解开封印之门的文字,封印之门将会开启。

蒜头君战斗力超强,但是不擅计算,请你帮忙蒜头君计算至少需要操作多少次才能解开封印之门。

输入格式

输入第一行一个字符串,长度不大于 100010001000,只包含小写字母,表示封印之门上的文字。

输入第二行一个字符串,只包含小写字母,保证长度和第一个字符串相等,表示能解开封印之门的文字。

输入第三行一个整数 k(0≤k≤676)k(0 \le k \le 676)k(0k676)

接下来 kkk 行,每行输出两个空格隔开的字符 aaa, bbb,表示一次操作能把字符 aaa 变换成字符 bbb

输出格式

如果蒜头君能开启封印之门,输出最少的操作次数。否则输出一行 −1-11

样例输入

abcd
dddd
3
a b
b c
c d

样例输出

6

从一个字符变到另一个字符本质上就是图论中的连通,用邻接矩阵存一下图(可到达的点)

然后比较两个串的对应字符是否可达,用floyd算法求出最短路程,如果可达直接加上最短路程,否则不可达

也就不可能得到最终串

code:

#include 
#include 
#include 
using namespace std;
const int INF = 0x3f3f3f3f;
int G[30][30];
int main(){
    for(int i = 0; i < 26; i++){
        for(int j = 0; j < 26; j++){
            if(i == j)
               G[i][j] = 0;
            else
               G[i][j] = INF;
        }
    }
    string s1,s2;
    cin >> s1 >> s2;
    int k;
    cin >> k;
    while(k--){
        char a,b;
        cin >> a >> b;
        if(a != b)
            G[a-'a'][b-'a'] = 1;
    }
    for(int k = 0; k < 26; k++){
        for(int i = 0; i < 26; i++){
            for(int j = 0; j < 26; j++){
                G[i][j] = min(G[i][j],G[i][k]+G[k][j]);
            }
        }
    }
    int sum = 0;
    for(int i = 0; i < s1.size(); i++){
        if(G[s1[i]-'a'][s2[i]-'a'] >= INF){
            sum = -1;
            break;
        }
        else
            sum += G[s1[i]-'a'][s2[i]-'a'];
    }
    cout << sum << endl;
    return 0;
}

你可能感兴趣的:(最短路径)