状态设计:d[i,j](k)表示经过k条边的i到j的最短路。因为用了迭代的方法,所以可以省略。
状态转移:d[i,j](M)=d[i,k](M >>1)+d[k,j](M>>1)
代码:
program poj3613;//By_thispoet
const
maxn=105;
var
i,j,k,m,n,p,q,s,e,tot :longint;
num :array[0..maxn*10]of longint;
d,b,map :array[0..maxn,0..maxn]of longint;
function hash(i:longint):longint;
begin
if num[i]=0 then
begin
inc(tot);num[i]:=tot;
end;
exit(num[i]);
end;
function min(i,j:int64):int64;
begin
if i<j then exit(i);exit(j);
end;
begin
readln(n,m,s,e);
filldword(map,sizeof(map)shr 2,maxlongint);
while m>0 do
begin
readln(j,p,q);
p:=hash(p);q:=hash(q);
map[p,q]:=j;map[q,p]:=j;
dec(m);
end;
filldword(d,sizeof(d)shr 2,maxlongint);
for i:=1 to tot do d[i,i]:=0;
while n>0 do
begin
if n and 1=1 then
begin
filldword(b,sizeof(b)shr 2,maxlongint);
for i:=1 to tot do
for j:=1 to tot do
for k:=1 to tot do
if (map[i,k]<maxlongint)and(d[k,j]<maxlongint) then b[i,j]:=min(b[i,j],map[i,k]+d[k,j]);
d:=b;
end;
filldword(b,sizeof(b)shr 2,maxlongint);
for i:=1 to tot do
for j:=1 to tot do
for k:=1 to tot do
if (map[i,k]<maxlongint)and(map[k,j]<maxlongint) then b[i,j]:=min(b[i,j],map[i,k]+map[k,j]);
map:=b;
n:=n >> 1;
end;
writeln(d[num[s],num[e]]);
end.