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

206 篇文章 0 订阅
27 篇文章 0 订阅

题目大意:
给出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 head<tail do
                     begin
                          inc(head);
                          i:=list[c[head]];
                          while i>0 do
                                begin
                                      if d[s[i]]+d[w[i]]<d[t[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.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值