bzoj 1060 贪心

  设根到每个叶子节点的距离为dis,比较容易的看出来,我们需要把这颗树的所有叶子节点的值都变成其中最大的内个,我们设为max,那么对于一颗子树来说,设其中dis值最大的为x,我们需要将这个子树根节点和子树根节点的父亲节点的边的值增加max-x,这时从贪心的角度来考虑,因为不论如何,对于当前最大的这个点来说,我们都需要将他的值增加max-x,那么我们只需要让这增加的更有价值,也就是使更多需要增加的点都被增加些,那么因为不能加多,所以取得是最大的点的dis值。那么dfs一遍就行了。

  反思:过程中申请变量没有赋初值。

  ps:这道题的数据有问题,生成输出数据的标程没有开longlong,开的是int,会自然溢出,所以pascal如果不手动模拟c++溢出是过不了的。

/**************************************************************

    Problem: 1060

    User: BLADEVIL

    Language: Pascal

    Result: Wrong_Answer

****************************************************************/

 

//By BLADEVIL

var

    n                       :longint;

    pre, other, len         :array[0..1000010] of longint;

    root                    :longint;

    last                    :array[0..500010] of longint;

    l                       :longint;

    ans                     :int64;

    max1, dis               :array[0..500010] of longint;

      

procedure connect(x,y,z:longint);

begin

    inc(l);

    pre[l]:=last[x];

    last[x]:=l;

    other[l]:=y;

    len[l]:=z;

end;

  

procedure dfs(x,fa:longint);

var

    q, p                    :longint;

begin

    q:=last[x];

    max1[x]:=x;

    while q<>0 do

    begin

        p:=other[q];

        if p=fa then

        begin

            q:=pre[q];

            continue;

        end;

        dis[p]:=dis[x]+len[q];

        dfs(p,x);

        if dis[max1[p]]>dis[max1[x]] then max1[x]:=max1[p];

        q:=pre[q];

    end;

end;

  

procedure make(x,fa,tmp:longint);

var

    q, p                    :longint;

    up, use                 :longint;

begin

    up:=dis[max1[root]];

    use:=0;

    if fa<>0 then

    begin

        use:=up-tmp-dis[max1[x]];

        ans:=ans+use;

    end;

    q:=last[x];

    while q<>0 do

    begin

        p:=other[q];

        if p=fa then

        begin

            q:=pre[q];

            continue;

        end;

        make(p,x,tmp+use);

        q:=pre[q];

    end;

end;

  

procedure init;

var

    i                       :longint;

    x, y, z                 :longint;

begin

    read(n,root);

    for i:=1 to n-1 do

    begin

        read(x,y,z);

        connect(x,y,z);

        connect(y,x,z);

    end;

    dfs(root,0);

end;

  

procedure main;

begin

    make(root,0,0);

    writeln(ans);

end;

  

begin

    init;

    main;

end.

 

你可能感兴趣的:(ZOJ)