当前位置: 代码迷 >> 综合 >> [bzoj4956][最短路][Floyd]Secret Chamber at Mount Rushmore
  详细解决方案

[bzoj4956][最短路][Floyd]Secret Chamber at Mount Rushmore

热度:47   发布时间:2023-12-19 05:30:50.0

Description

你现在可能已经听说过Rushmore山上有一个壮观的石雕刻画了四位著名的美国总统。然而,很少有人知道这个纪念
雕刻暗藏一个秘密的房间。这听起来像是一部好莱坞电影的情节,但是这个房间是真实存在的。它藏在Abraham Lin
coln的头后面,它被设计成一个档案库,用来存放美国历史上重要的文件与文物。历史学家声称这个档案库的建造在
1939年被中断,直到20世纪90年代末才能被访问,但这不是全部的真相。在1982年,著名的考古学家S. Dakota Jones
秘密地访问了这座纪念雕刻,发现房间已经完成建造,但不对外公开。这似乎有些可疑,经过一些开凿,她发现一个隐
藏的地下室和一些文件。不幸的是,这些文件没什么有效信息,都是很无聊的内容。她猜测这些内容被加密了,但是
她费尽心机还是无法解密。在这周的前些时候, Jones博士在当地参加ACM-ICPC世界总决赛, 她终于在South Dakot
aSchool of Mines and Technology的Connolly
Hall发现了破译这些文件的密钥。她发现文件包含了一系列字母转
换规则。一些字母可以经过多次转换,但一些字母没有转换规则。经过对那份无聊的文件中的单词多次转换之后,她
似乎能把内容破译成美国历史上的文件,例如独立宣言和美国宪法。她需要你的帮助。你将得到字母可能的转换规
则和一系列原始单词与解密单词。你的任务是验证每对单词是否匹配。如果两个单词具有相同的长度,且第一个单
词的每个字母可以用转换规则多次转换后变成第二个单词中对应位置的字母,则两个单词匹配。

Input

第一行包含两个整数m(1≤m≤500)和n(1≤n≤50),其中m表示字母转换规则的数量,n表示单词对的数量。
接下来m行,每行包含两个不同的字母a和b,表示字母a可以转换成字母b。每个有序对(a,b)只会出现至多一次。 接下来n
行,每行包含一对需要检查的单词。 转换规则和单词只会使用小写字母’a’到’z’,且每个单词包含至少1个字母,至多50个字母。

Output

对于每对单词,如果两个单词可以匹配,输出yes,否则输出no。

Sample Input

样例1

9 5

c t

i r

k p

o c

r o

t e

t f

u h

w p

we we

can the

work people

it of

out the

样例2

3 3

a c

b a

a b

aaa abc

abc aaa

acm bcm

Sample Output

样例1

yes

no

no

yes

yes

样例2

yes

no

yes

题解

有向图的询问一个节点能否到达另一个节点的问题
由于这张图的大小不会超过26*26,所以可以直接floyd预处理,然后On判
无向图就更简单直接并查集就好了。。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int mp[30][30];
int n,m;
char cx[60],cy[60];
int main()
{memset(mp,63,sizeof(mp));scanf("%d%d",&m,&n);for(int i=1;i<=26;i++)mp[i][i]=1;for(int i=1;i<=m;i++){scanf("%s%s",cx+1,cy+1);mp[cx[1]-'a'+1][cy[1]-'a'+1]=1;}for(int k=1;k<=26;k++)for(int i=1;i<=26;i++)if(k!=i)for(int j=1;j<=26;j++)if(i!=j && k!=j)mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);while(n--){scanf("%s%s",cx+1,cy+1);int lx=strlen(cx+1),ly=strlen(cy+1);if(lx!=ly){
   printf("no\n");continue;}bool bk=false;for(int i=1;i<=lx;i++)if(mp[cx[i]-'a'+1][cy[i]-'a'+1]==1061109567){bk=true;break;}if(bk==false)printf("yes\n");else printf("no\n");}return 0;
}