状态设计: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.