SSL P2516 2014年中山市选拔赛 dwarf tower

题目大意:
给出N个物品直接购买的价格,以及M组合成方式,即物品x与物品y可以合成物品z,求出获得第1个物品的最小花费。

题解:
spfa:
d[i]表示合成第i个物品的最小值。
1.d[i]的初值是一开始直接购买第i个物品的值。
2.m组x,y,z,对于每组x,y,z,可以变成2条权值边,即x到z,权值为d[y],y到z,权值为d[x]。
3.枚举物品,以第i个物品为起点做spfa,做n次,找出最短路,即最少花费。
时间复杂度:O(knm),k是一个极小的值,所以不会超时。

var
      s,t,w,next,c:array [0..200001] of longint;
      list,d:array [0..10001] of longint;
      v:array [0..10001] of boolean;
      p,i,j,n,m,x,y,z:longint;

procedure spfa;
var
        head,tail,i,j:longint;
begin
        for j:=1 to n do
            begin
               v[j]:=true;
               head:=0;
               tail:=1;
               c[1]:=j;
               while headdo
                     begin
                          inc(head);
                          i:=list[c[head]];
                          while i>0 do
                                begin
                                      if d[s[i]]+d[w[i]]then begin
                                                    d[t[i]]:=d[s[i]]+d[w[i]];
                                                    if v[t[i]]=false then
                                                       begin
                                                             v[t[i]]:=true;
                                                             inc(tail);
                                                             c[tail]:=t[i];
                                                       end;
                                            end;
                                      i:=next[i];
                                end;
                          v[c[head]]:=false;
                    end;
            end;
end;

begin
      readln(n,m);
      for i:=1 to n do
          begin
               read(d[i]);
               v[i]:=false;
          end;
      readln;
      for i:=1 to m do
          begin
               readln(z,x,y);
               inc(p);
               s[p]:=x; t[p]:=z; w[p]:=y;
               next[p]:=list[s[p]];
               list[s[p]]:=p;
               inc(p);
               s[p]:=y; t[p]:=z; w[p]:=x;
               next[p]:=list[s[p]];
               list[s[p]]:=p;
          end;
      spfa;
      writeln(d[1]);
end.

你可能感兴趣的:(pascal,spfa,邻接表,暴力/枚举/模拟)