修路
题目描述
输入格式
输出格式
样例输入
3 3
1 2 3
1 2 21
1 3 21
2 3 22
样例输出
34
数据范围
样例解释
题解
对与每一条边进行讨论。
设连边的总花费为
C
。
如果我们选择了第
其中
ui
和
vi
是第
i
条边的的两个端点。
所以事实上,总花费
因此,我们不妨不把 costi 换成 costi -( aui + avi ),然后再对这 m <script type="math/tex" id="MathJax-Element-18">m</script>条边排一遍序,做一遍最小生成树即可。
Code(Pascal)
var
ans:int64;
n,m,j,k,l,i,o,p,f1,f2:longint;
s,fa:array[0..100100] of longint;
bj:array[0..100100,1..3] of int64;
procedure sjzl;
var
i,k:longint;
begin
for i:=1 to n do
fa[i]:=i;
randomize;
for i:=1 to m div 2 do
begin
k:=random(m div 2)+1;
bj[0]:=bj[i];
bj[i]:=bj[k];
bj[k]:=bj[0];
end;
end;
procedure qsort(l,r:longint);
var
mid:int64;
i,j:longint;
begin
i:=l;
j:=r;
mid:=bj[(l+r) div 2,3];
repeat
while bj[i,3]<mid do inc(i);
while bj[j,3]>mid do dec(j);
if i<=j then
begin
bj[0]:=bj[i];
bj[i]:=bj[j];
bj[j]:=bj[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
function look(o:longint):longint;
begin
if fa[o]=o then exit(o);
fa[o]:=look(fa[o]);
exit(fa[o]);
end;
begin
readln(n,m);
for i:=1 to n do
read(s[i]);
readln;
for i:=1 to m do
begin
readln(bj[i,1],bj[i,2],bj[i,3]);
bj[i,3]:=bj[i,3]-s[bj[i,1]]-s[bj[i,2]];
end;
sjzl;
qsort(1,m);
for i:=1 to m do
if look(bj[i,1])<>look(bj[i,2]) then
begin
f1:=look(bj[i,1]);
f2:=look(bj[i,2]);
fa[f2]:=f1;
ans:=ans+bj[i,3];
end;
writeln(ans);
end.