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.