【BZOJ1003】物流运输trans

来源:互联网 发布:淘宝网圾踞一代皮鞋 编辑:程序博客网 时间:2024/05/10 13:24

物流公司要把一批货物从码头A运到码头B。由于货物量比较大,需要n天才能运完。货物运输过程中一般要转停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。由于各种因素的存在,有的时候某个码头会无法装卸货物。这时候就必须修改运输路线,让货物能够按时到达目的地。但是修改路线是一件十分麻烦的事情,会带来额外的成本。因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小。



【题解】

DP+SPFA,因为数据很小所以可以暴力,主要还是练习一下算法


【代码】

program p1003;type  td = record    st, ed: longint;  end;var  f: array[0..105] of int64;  a: array[0..20, 0..20] of int64;  b: array[0..20] of longint;  c: array[0..20, 0..20] of td;  q: array[0..20] of longint;  d0: array[0..20] of int64;  pd: array[0..20] of boolean;  n, m, e, d, i, j, x, y, p: longint;  k, l: int64;  function ck(m, x, y: longint): boolean;  var    i: longint;  begin    ck := True;    for i := 1 to b[m] do      if ((x <= c[m, i].st) and (c[m, i].st <= y)) or        ((x <= c[m, i].ed) and (c[m, i].ed <= y) or        ((c[m, i].st < x) and (c[m, i].ed > y))) then        exit(False);  end;  function SPFA(e, b: longint): int64;  var    head, i, j, tail: longint;  begin    for i := 1 to 20 do      d0[i] := 1073741824;    for i := 1 to 20 do      pd[i] := False;    head := 0;    tail := 1;    q[tail] := 1;    d0[1] := 0;    pd[1] := True;    repeat      Inc(head);      if head = 21 then        head := 1;      j := q[head];      pd[j] := False;      for i := 1 to m do        if i <> j then          if ck(i, b, e) then            if (a[j, i] > 0) and (int64(d0[j] + a[j, i]) < d0[i]) then            begin              d0[i] := int64(d0[j] + a[j, i]);              if not pd[i] then              begin                pd[i] := True;                Inc(tail);                if tail = 21 then                  tail := 1;                q[tail] := i;              end;            end;    until head = tail;    exit(d0[m]);  end;begin  fillchar(a, sizeof(a), 0);  fillchar(b, sizeof(b), 0);  readln(n, m, k, e);  for i := 1 to e do  begin    readln(x, y, p);    if (a[x, y] = 0) or (p < a[x, y]) then    begin      a[x, y] := p;      a[y, x] := p;    end;  end;  readln(d);  for i := 1 to d do  begin    readln(p, x, y);    Inc(b[p]);    c[p, b[p]].st := x;    c[p, b[p]].ed := y;  end;  f[0] := -k;  for i := 1 to 105 do    f[i] := 1073741824;  for i := 1 to n do    for j := 0 to i - 1 do    begin      l := f[j] + int64(SPFA(i, j + 1) * int64(i - j)) + k;      if l < f[i] then        f[i] := l;    end;  writeln(f[n]);end.

0 0