poj3013

来源:互联网 发布:女生网络钓鱼 编辑:程序博客网 时间:2024/06/01 10:33

【题意】

给定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.