我们用dis[i,j]代表到i这个点,用j张票的最短路程,那么我们只需要在SPFA更新
的时候,用dis[i,j]更新dis[p,j]和dis[p,j+1]就行了
/************************************************************** Problem: 2662 User: BLADEVIL Language: Pascal Result: Accepted Time:4 ms Memory:376 kb ****************************************************************/ //By BLADEVIL type rec =record x, use :longint; end; var n, m, k :longint; pre, other, len :array[0..2010] of longint; last :array[0..100] of longint; l :longint; dis :array[0..100,0..100] of longint; flag :array[0..100,0..100] of boolean; que :array[0..10000] of rec; ans :longint; function min(a,b:longint):longint; begin if a>b then min:=b else min:=a; end; procedure connect(x,y,z:longint); begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y; len[l]:=z; end; procedure init; var i :longint; x, y, z :longint; begin read(n,m,k); for i:=1 to m do begin read(x,y,z); connect(x,y,z); connect(y,x,z); end; end; procedure main; var h, t, q, p :longint; cur, ti :longint; i :longint; begin filldword(dis,sizeof(dis) div 4,maxlongint div 10); dis[1,0]:=0; h:=0; t:=1; que[1].x:=1; que[1].use:=0; while h<>t do begin h:=h mod 10000+1; cur:=que[h].x; ti:=que[h].use; flag[cur,ti]:=false; q:=last[cur]; while q<>0 do begin p:=other[q]; if dis[cur,ti]+len[q]<dis[p,ti] then begin dis[p,ti]:=dis[cur,ti]+len[q]; if not flag[p,ti] then begin t:=t mod 10000+1; que[t].x:=p; que[t].use:=ti; flag[p,ti]:=true; end; end; if ti<k then begin if dis[cur,ti]+len[q] div 2<dis[p,ti+1] then begin dis[p,ti+1]:=dis[cur,ti]+len[q] div 2; if not flag[p,ti+1] then begin t:=t mod 10000+1; que[t].x:=p; que[t].use:=ti+1; flag[p,ti+1]:=true; end; end; end; q:=pre[q]; end; end; ans:=maxlongint; for i:=0 to k do ans:=min(ans,dis[n,i]); writeln(ans); end; begin init; main; end.
/************************************************************** Problem: 2763 User: BLADEVIL Language: Pascal Result: Accepted Time:9472 ms Memory:2804 kb ****************************************************************/ //By BLADEVIL type rec =record x, use :longint; end; var n, m, k :longint; pre, other, len :array[0..100010] of longint; last :array[0..10010] of longint; l :longint; dis :array[0..10000,0..11] of longint; flag :array[0..10000,0..11] of boolean; que :array[0..100010] of rec; ans :longint; st, fin :longint; function min(a,b:longint):longint; begin if a>b then min:=b else min:=a; end; procedure connect(x,y,z:longint); begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y; len[l]:=z; end; procedure init; var i :longint; x, y, z :longint; begin read(n,m,k); read(st,fin); for i:=1 to m do begin read(x,y,z); connect(x,y,z); connect(y,x,z); end; end; procedure main; var h, t, q, p :longint; cur, ti :longint; i :longint; begin filldword(dis,sizeof(dis) div 4,maxlongint div 10); dis[st,0]:=0; h:=0; t:=1; que[1].x:=st; que[1].use:=0; while h<>t do begin h:=h mod 100000+1; cur:=que[h].x; ti:=que[h].use; flag[cur,ti]:=false; q:=last[cur]; while q<>0 do begin p:=other[q]; if dis[cur,ti]+len[q]<dis[p,ti] then begin dis[p,ti]:=dis[cur,ti]+len[q]; if not flag[p,ti] then begin t:=t mod 100000+1; que[t].x:=p; que[t].use:=ti; flag[p,ti]:=true; end; end; if ti<k then begin if dis[cur,ti]<dis[p,ti+1] then begin dis[p,ti+1]:=dis[cur,ti]; if not flag[p,ti+1] then begin t:=t mod 100000+1; que[t].x:=p; que[t].use:=ti+1; flag[p,ti+1]:=true; end; end; end; q:=pre[q]; end; end; ans:=maxlongint; for i:=0 to k do ans:=min(ans,dis[fin,i]); writeln(ans); end; begin init; main; end.