题解:cheering up the cows[USACO2008 NOV]

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.  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值