已知字母A,B和一组字母变换规则(至多100个规则): A1->B1 A2->B2 规则的含义为:如果A=Ak,可以通过一次变换为Bk(1≤k ≤ 规则数) 求从A到B最少需要几次变换。
【输入文件】letter.in
第一行为两个字母,分别是初始字母和变换目标字母。 以下k行为变换规则(1 ≤ k ≤ 100),都是大写字母,两个字母间以空格间隔,直到文件结束。
【输出文件】letter.out
最小的变换次数。如果无法变换,则输入”No Answer!”
【样例数据】
【输入】letter.in
A Z
A E
E F
F T
T Z
A C
C Z
【输出】letter.out
2
参考程序
{【算法分析】如果我们建一张有向图,把每一个字母看作结点,
那么变换AK->BK就是一条从AK到BK的权为1的有向边,
那么变换需要的步数就是起点到终点的最短路径长度。
可以应用经典的dijkstra算法}
program letter;
type
path=record
length:integer;
pre:'A'..'Z';
end;
var
w:array['A'..'Z','A'..'Z'] of integer;
dist:array['A'..'Z'] of path;
s,t,x,y,u,i,j,ch:char;
procedure init;
begin
assign(input,'letter.in');
reset(input);
assign(output,'letter.out');
rewrite(output);
readln(s,ch,t); {因为是字母,之间的空格必须略过}
for x:='A' to 'Z' do
for y:='A' to 'Z' do
if x<>y
then w[x,y]:=101 {最多100个规则,所以最大值101就够了}
else w[x,y]:=0;
while not eof(input) do
begin
readln(x,ch,y);
w[x,y]:=1;
end;
end;
procedure dijkstra(v0:char);
var
min:integer;
begin
w[v0,v0]:=1;
for i:='A' to 'Z' do
begin
dist[i].length:=w[v0,i];
if dist[i].length<>101
then dist[i].pre:=v0;
end;
repeat
min:=101;
u:=' ';
for i:='A' to 'Z' do
if (w[i,i]=0) and (dist[i].length<min)
then begin
u:=i;
min:=dist[i].length;
end;
if u<>' '
then begin
w[u,u]:=1;
for i:='A' to 'Z' do
if (w[i,i]=0) and (dist[i].length>dist[u].length+w[u,i])
then begin
dist[i].length:=dist[u].length+w[u,i];
dist[i].pre:=u;
end;
end;
until u=' ';
end;
begin
init;
dijkstra(s);
if dist[t].length<>101
then write(dist[t].length)
else write('No Answer!')
close(input);
close(output);
end.