BZoj 1003 物流运输 DP+最短路
2013-09-11 09:56
W[I]代表前I天能取得的最小花费,假设在第J天更改一次路线,那么如果有
W[I]>W[J]+第j+1到第I天的最小花费+更改路线的花费(K) 那么更新W[I];
用最短路求第J+1到I的最短路*(I-J),边界则是W[1]=0;
因为最开始的路线不用更改(就是最初的路线不算在更改的费用中),这个
方程默认第一次的路线就是更改后的,多加了一次K,所以最后输出W[I]-K;
//By BLADEVIL var connect :array[0..110,0..110] of longint; n, m, k, e, ch :longint; c :array[0..110,0..110] of longint; w :array[0..110] of longint; d :array[0..110] of longint; vis :array[0..1100] of boolean; procedure init; var i, j :longint; x, y, z :longint; begin assign(input,'santajs.in'); reset(input); assign(output,'santajs.out'); rewrite(output); read(n,m,k,e); fillchar(connect,sizeof(connect),10); for i:=1 to e do begin read(x,y,z); if z<connect[x,y] then begin connect[x,y]:=z; connect[y,x]:=z; end; end; read(ch); for i:=1 to ch do begin read(x,y,z); for j:=y to z do begin inc(c[j,0]); c[j,c[j,0]]:=x; end; end; end; function dijkstra(s,t:longint):longint; var i, j, max, k :longint; begin fillchar(vis,sizeof(vis),false); for i:=1 to m do d[i]:=maxlongint; d[1]:=0; for i:=s to t do for j:=1 to c[i,0] do vis[c[i,j]]:=true; for i:=1 to m-1 do begin max:=maxlongint; for j:=1 to m do if (not vis[j]) and (d[j]<max) then begin k:=j; max:=d[j]; end; vis[k]:=true; for j:=1 to m do if d[j]>d[k]+connect[k,j] then d[j]:=d[k]+connect[k,j]; end; exit(d[m]); end; procedure dp; var i, j, x :longint; begin for i:=1 to n do begin w[i]:=maxlongint div 10; for j:=0 to i-1 do begin x:=dijkstra(j+1,i); if x>100000000 then continue; if w[i]>w[j]+k+(i-j)*x then w[i]:=w[j]+k+(i-j)*x; end; end; writeln(w[n]-k); close(input); close(output); end; begin init; dp; end.