题目链接:https://hpuoj.com/contest/23/problem/I/
I. Same String
单点时限: 2.0 sec
内存限制: 512 MB
有两个只由小写字母组成的长度为n的字符串s1,s2和m组字母对应关系,每一组关系由两个字母c1和c2组成,代表c1可以直接变成c2,你需要判断s1是否可以通过这m组关系转换为s2。
输入格式
第一行输入一个n(1≤n≤100),代表字符串的长度。
第二行和第三行输入两个字符串s1,s2。
第四行输入一个m(1≤m≤325),代表有m组关系。
接下来m行,第i行两个字符ui,vi,代表ui可以直接变为vi。
输出格式
如果s1可以通过这些m组关系转化变为s2,输出”YES”,否则输出”NO”。
分析:
把出现的字母当作点a能变成b就说明a到b有一条边
建图,注意是有向图。
然后遍历一遍,我没想到什么好的方法,用了floyd最短路算法,这样就能直接判断一个点是否可以到达另一个点。
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 30;
int G[N][N];
int dp[N][N];
void floyd() // floyd最短路算法
{
for(int k=0; k<N; k++)
{
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
}
}
}
}
int main()
{
int n;
char s1[107], s2[107];
while(scanf("%d", &n) != EOF)
{
getchar();
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
if(i == j) dp[i][j] = 0;
else dp[i][j] = INF;
}
}
scanf("%s %s", s1, s2);
// printf("s1 = %s s2 = %s\n", s1, s2);
int m;
scanf("%d", &m);
// printf("m = %d\n", m);
getchar();
for(int i=0; i<m; i++)
{
char u, v;
scanf("%c %c", &u, &v);
getchar();
// printf("u = %c v = %c\n", u, v);
dp[u-'a'][v-'a'] = 1;
}
floyd();
int i;
for(i=0; i<n; i++)
{
if(dp[s1[i] - 'a'][s2[i] - 'a'] != INF)
continue;
else
break;
}
if(i == n)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}