------------只要够努力,人生最坏的结局不过是大器晚成!!!

https://nanti.jisuanke.com/t/20692

                                                                                       封印之门

问答

  •  18.65%
  •  1000ms
  •  262144K
 

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

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

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

输入格式

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

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

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

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

输出格式

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

样例输入

abcd
dddd
3
a b
b c
c d

样例输出

6
思路:开始一直以为就是一个简单的深搜,于是我用了邻接表去搜,但一直超时,最终看了大佬的代码发现竟然是一道考最短路的题。看到这句话赶紧回来写了一波,既然有可能匹配每一个,则要知道
每个点之间的距离,所以用弗洛伊德,同时存储路径时都减一个a化为整数去做。
#include <bits/stdc++.h>
using namespace std;
int mp[30][30];
int n = 28;
const int INF = 0x3f3f3f3f;

void floyd(){
	for(int k = 0; k < n; k++){
		for(int i = 0; i < n; i++){
			for(int j = 0; j < n; j++){
				if(mp[i][j] > mp[i][k] + mp[k][j])
					mp[i][j] = mp[i][k] + mp[k][j];
			}
		}
	}
} 

int main(){
	string str, mu;
	int m;
	cin >> str >> mu;
	cin >> m;
	memset(mp, INF, sizeof(mp));
	for(int i = 0; i < m; i++){
		char x, y;
		cin >> x >> y;
		mp[x - 'a'][y - 'a'] = 1;
	}
	floyd();
	int ans = 0;
	for(int i = 0; i < str.length(); i++){
		if(str[i] == mu[i])
			continue; 
		if(mp[str[i] - 'a'][mu[i] - 'a'] < INF)
			ans += mp[str[i] - 'a'][mu[i] - 'a'];
		else{
			cout << -1 << endl;
			continue;
		}
	}
	cout << ans << endl;
	return 0;
}

  



posted on 2018-03-09 21:08  ystraw  阅读(309)  评论(0)    收藏  举报

不经一番切孤寒,怎得梅花扑鼻香