题目大意:
给出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.