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.

 

posted on 2014-01-20 17:22  BLADEVIL  阅读(304)  评论(0编辑  收藏  举报