bzoj1232

时间:2023-03-10 06:29:21
bzoj1232

由题意知,最后要保留的边肯定都要被走过

来回一条边所花费的时间=2*边长+安慰边两端的牛所要花的时间和

总时间就等于所保留边来回的时间和+根节点时间;

不难想到做一下最小生成树即可

贪心可知,根一定选在需要安慰时间最小的那个点

 type node=record
       x,y,len:longint;
     end;
var a:array[..] of node;
    fa,w:array[..] of longint;
    n,m,ans,i,j,k1,k2:longint; function getf(x:longint):longint;
  begin
    if x<>fa[x] then fa[x]:=getf(fa[x]);
    exit(fa[x]);
  end; procedure swap(var a,b:node);
  var c:node;
  begin
    c:=a;
    a:=b;
    b:=c;
  end; procedure sort(l,r:longint);
  var i,j,p,q: longint;
  begin
    i:=l;
    j:=r;
    p:=a[(l+r) shr ].len;
    repeat
      while (a[i].len<p) do inc(i);
      while (p<a[j].len) do dec(j);
      if not(i>j) then
      begin
        swap(a[i],a[j]);
        inc(i);
        j:=j-;
      end;
    until i>j;
    if l<j then sort(l,j);
    if i<r then sort(i,r);
  end; begin
  readln(n,m);
  ans:=;
  for i:= to n do
  begin
    readln(w[i]);
    if w[i]<ans then ans:=w[i];
    fa[i]:=i;
  end;
  for i:= to m do
  begin
    readln(a[i].x,a[i].y,a[i].len);
    a[i].len:=a[i].len*+w[a[i].x]+w[a[i].y];
  end;
  sort(,m);
  i:=;
  j:=;
  while i<n- do
  begin
    inc(j);
    k1:=getf(a[j].x);
    k2:=getf(a[j].y);
    if k1<>k2 then
    begin
      inc(i);
      fa[k1]:=k2;
      ans:=ans+a[j].len;
    end;
  end;
  writeln(ans);
end.