poj1062 昂贵的聘礼 dij

来源:互联网 发布:linux可执行文件.o 编辑:程序博客网 时间:2024/05/17 04:11

题目大意

  中文题,题目大意就不说了。(注意,等级限制是包括间接地交易的。如一的等级是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.


2 1