https://www.luogu.org/problem/show?pid=2916
容易证明:
1.生成树上每条路径走两遍;
2.每一个节点走的次数为它所连的边的数目,根节点增加一次。
那么一个很自然的想法就产生了:
把每一条路径的值*2再加上它所连节点的值,跑一遍kruskal就行,把最小的节点作为根。
好吧,水题一道,贴代码:
const maxn=10001;
maxp=1000002;
type gragh=record
x,y,l:longint;
end;
var e:array[0..maxp] of gragh;
c,father:array[0..maxn]of longint;
i,j,n,p,k,u,v,ans:longint;
procedure qsort(l,r:longint);
var tmp:gragh;
mid,j,i:longint;
begin
i:=l;j:=r;mid:=e[(l+r)>>1].l;
while i<j do
begin
while e[i].l<mid do inc(i);
while e[j].l>mid do dec(j);
if i<=j then
begin
tmp:=e[i];e[i]:=e[j];e[j]:=tmp;
inc(i);dec(j);
end;
end;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
function find(i:longint):longint;
begin
if father[i]<>i then
father[i]:=find(father[i]);
exit(father[i]);
end;
begin
//assign(input,'cheer.in');assign(output,'cheer.out');
//reset(input);rewrite(output);
readln(n,p);ans:=maxlongint;
for i:=1 to n do
begin
readln(c[i]);
if ans>c[i] then ans:=c[i];
end;
for i:=1 to p do
begin
readln(e[i].x,e[i].y,e[i].l);
e[i].l:=e[i].l*2+c[e[i].x]+c[e[i].y];
end;
qsort(1,p);k:=0;
for i:=1 to n do father[i]:=i;
for i:=1 to p do
begin
if k=n-1 then break;
u:=e[i].x;v:=e[i].y;
if find(u)<>find(v) then
begin
inc(k);//writeln(u,' ',v);
inc(ans,e[i].l);
father[find(u)]:=find(v);
end;
end;
writeln(ans);
//close(input);close(output);
end.