原題連接html
蒜頭君被暗黑軍團包圍在一座島上,全部通往近衛軍團的路都有暗黑軍團把手。幸運的是,小島上有一扇上古之神打造的封印之門,能夠通往近衛軍團,傳聞至今沒有人能解除封印。
封印之門上有一串文字,只包含小寫字母,有 k k k 種操做規則,每一個規則能夠把一個字符變換成另一個字符。通過任意屢次操做之後,最後若是能把封印之門上的文字變換成解開封印之門的文字,封印之門將會開啓。
蒜頭君戰鬥力超強,可是不擅計算,請你幫忙蒜頭君計算至少須要操做多少次才能解開封印之門。ios輸入格式
輸入第一行一個字符串,長度不大於 10001000 10001000 10001000,只包含小寫字母,表示封印之門上的文字。
輸入第二行一個字符串,只包含小寫字母,保證長度和第一個字符串相等,表示能解開封印之門的文字。
輸入第三行一個整數 k ( 0 ≤ k ≤ 676 ) k(0≤k≤676) k(0≤k≤676)
接下來 k k k 行,每行輸出兩個空格隔開的字符 a a a, b b b,表示一次操做能把字符 a a a 變換成字符 b b bweb輸出格式
若是蒜頭君能開啓封印之門,輸出最少的操做次數。不然輸出一行 − 1 −1 −1svg
輸入樣例
abcd dddd 3 a b b c c d
輸出樣例
6
此題其實是一個全源最短路問題,
能看透題目的包裝, 就成功一半了
給出的變換規則,至關於有向圖中的有向邊
給出的兩個字符串, 至關於至關於有向圖中的頂點
求將字符串 1 1 1變爲字符串 2 2 2的最少的操做次數, 至關於求兩點間最短路徑
頂點的個數 k ( 0 ≤ k ≤ 676 ) k(0≤k≤676) k(0≤k≤676), 因此能夠用Floyd
來解決spa
注意:
1.圖爲有向圖.(爲何是有向圖? 每一個規則能夠把一個字符變換成另一個字符,因此是有向圖)
2.輸入數據中可能存在端點相同的數據(如 a a a\ a a a),再存圖時須要忽略debug
// 沒想到, 居然是最短路 Debug: 有向圖而不是無向圖 #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; string str, p; int k; long long dis[29][29]; void init() { for(int i=0; i<26; i++) for(int j=0; j<26; j++) if(i != j) dis[i][j] = INF; } int main() { cin >> str >> p; cin >> k; init(); for(int i=0; i<k; i++) { char a, b; cin >> a >> b; if(a==b) continue; // debug: 輸入數據中, 可能存在兩個端點相同 dis[a-'a'][b-'a'] = 1; } for(int i=0; i<26; i++) for(int j=0; j<26; j++) for(int k=0; k<26; k++) dis[j][k] = min(dis[j][k], dis[j][i] + dis[i][k]); int sum = 0; for(int i = 0; i<str.size(); i++) { int val = dis[str[i]-'a'][p[i]-'a']; if(val >= INF) { sum = -1; break; } sum += val; } cout << sum << endl; return 0; }