【题意】
给定v个点的重量,并给定e条边,每条边具有一个权值,在e条边中选v-1条边使这v个点成为一棵树,设一棵树的代价为(每棵子树节点重量和其子树根到父节点的边的权值的乘积)之和,求以1为根节点的树的最小代价
【输入】
多组数据,第一行为一个数t,表示有t组数据
接下来每组数据第一行两个数v、e(<=50000)意义如上
接下来一行v个数描述各个点的重量
之后的e行表示e条边及其权值
【输出】
对于每组数据,输出一个数字表示其以1为根节点的树的最小代价
求以1为原点的各点最短路径,答案即为(各点【最短路径*重量】之和)
需要注意边是双向的,最多有100000条边
program poj3013;
var
all,tot,n,e,t,i,j,k,u,v,c,o:longint;
ans:int64;
l,r:array [0..1] of longint;
next,root,point,cost,w,dis:array [0..150001] of int64;
dl:array [0..1,-150001..150001] of longint;
procedure spfa;
begin
fillchar(dis,sizeof(dis),63);
o:=0;
l[o]:=0;
r[o]:=0;
dl[o,0]:=1;
dis[1]:=0;
while l[o]<=r[o] do
begin
o:=1-o;
l[o]:=0;
r[o]:=-1;
for i:=l[1-o] to r[1-o] do
begin
k:=root[dl[1-o,i]];
while k<>0 do
begin
if dis[dl[1-o,i]]+cost[k]<dis[point[k]] then
begin
dis[point[k]]:=dis[dl[1-o,i]]+cost[k];
if (l[o]<=r[o])and(dis[point[k]]<dis[dl[o,l[o]]]) then
begin
dec(l[o]);
dl[o,l[o]]:=point[k];
end
else
begin
inc(r[o]);
dl[o,r[o]]:=point[k];
end
end;
k:=next[k];
end;
end;
end;
end;
procedure connect (u,v,c:longint);
begin
inc(tot);
point[tot]:=v;
cost[tot]:=c;
next[tot]:=root[u];
root[u]:=tot;
end;
begin
read(t);
while t>0 do
begin
read(n,e);
for i:=1 to n do
read(w[i]);
fillchar(root,sizeof(root),0);
tot:=0;
for i:=1 to e do
begin
read(u,v,c);
connect(u,v,c);
connect(v,u,c);
end;
spfa;
ans:=0;
for i:=1 to n do
begin
if dis[i]=dis[0] then break;
ans:=ans+dis[i]*w[i];
end;
if dis[i]=dis[0] then writeln('No Answer')
else writeln(ans);
dec(t);
end;
end.