poj1062 昂贵的聘礼 dij

题目大意

  中文题,题目大意就不说了。(注意,等级限制是包括间接地交易的。如一的等级是3,二的等级是5,三的等级是7,等级限制是2;那就不能一和二交易,二又和三交易,因为一和三的等级相差超过2)

分析

  如果没有等级限制,那就分两步:

  一.建图,把每个物品看成一个节点,酋长的允诺也看作一个物品(点1),如果一个物品加上金币可以交换另一个物品,则这两个节点之间有边,权值为金币数,把0点和其他点都相连,权值为所连的物品的原价。(注意,是有向图)

  二.Dij,从0点出发,求到1点的最短路径.

  有等级限制,那就枚举等级下限。

代码

var
  f:array[1..200,1..200] of longint;
  v,d,a:array[0..200] of longint;
  i,j,k,l,x:longint;
  n,m:longint;
  ans,max:longint;

begin
  readln(m,n);
  fillchar(f,sizeof(f),$7f div 2);
  for i:=1 to n do
    begin
      readln(l,a[i],k);
      f[n+1,i]:=l;
      for j:=1 to k do
        begin
          read(x);
          readln(f[x,i]);
        end;
    end;
  n:=n+1;
  ans:=maxlongint;
  for x:=a[1]-m to a[1] do
  begin
  fillchar(d,sizeof(d),$7f div 2);
  fillchar(v,sizeof(v),0);
  d[n]:=0;
  for i:=1 to n do
    begin
      k:=maxlongint;
      l:=0;
      for j:=1 to n do
        if (v[j]=0) and (d[j]<k) and ((a[j]>=x) and (a[j]<=x+m) or (j=n))
          then
            begin
              k:=d[j];
              l:=j;
            end;
      v[l]:=1;
      if l=0 then break;
      for j:=1 to n do
        if (d[l]+f[l,j]<d[j]) and ((a[j]>=x) and (a[j]<=x+m) or (j=n))
          then d[j]:=d[l]+f[l,j];
    end;
  if ans>d[1] then ans:=d[1];
  end;
  write(ans);
end.


posted @ 2016-04-14 16:45  一个响亮的蒟蒻  阅读(131)  评论(0编辑  收藏  举报