• bzoj 2152 点剖分


    比较裸的点剖分,访问到每个重心时,记录一个b数组,

    代表当前子树中长度为i的边的数量是b[i],因为是3的倍数,

    所以边长mod 3保存就行了,然后记录一个sum数组,代表

    当前子树中一个子节点为根的子树中的情况(类似b),然后

    用这两个数组不断的更新答案就行了。

    /**************************************************************
        Problem: 2152
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:572 ms
        Memory:1360 kb
    ****************************************************************/
     
    //By BLADEVIL
    var
        n                               :longint;
        pre, other, len                 :array[0..40010] of longint;
        last                            :array[0..20010] of longint;
        l, top                          :longint;
        size, stack, yy                 :array[0..20010] of longint;
        ff                              :array[0..40010] of boolean;
        root                            :longint;
        b, sum                          :array[0..10] of longint;
        ans                                 :longint;
         
    function gcd(x,y:longint):longint;
    begin
        if x<y then exit(gcd(y,x)) else
        if y=0 then exit(x) else exit(gcd(y,x mod y));
    end;
         
    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_size(x,fa:longint);
    var
        q, p                            :longint;
    begin
        size[x]:=1;
        inc(top);
        stack[top]:=x;
        q:=last[x];
        while q<>0 do
        begin
            p:=other[q];
            if (ff[q]) or (p=fa) then
            begin
                q:=pre[q];
                continue;
            end;
            dfs_size(p,x);
            inc(size[x],size[p]);
            q:=pre[q];
        end;
        yy[x]:=fa;
    end;
     
    procedure getroot(u:longint);
    var
        ms, s, x, p, q                  :longint;
        i                               :longint;
    begin
        top:=0;
        dfs_size(u,0);
        ms:=maxlongint;
        for i:=1 to top do
        begin
            x:=stack[i];
            s:=size[u]-size[x];
            q:=last[x];
            while q<>0 do
            begin
                p:=other[q];
                if (ff[q]) or (p=yy[x]) then
                begin
                    q:=pre[q];
                    continue;
                end;
                if size[p]>s then s:=size[p];
                q:=pre[q];
            end;
            if s<ms then
            begin
                ms:=s;
                root:=x;
            end;
        end;
    end;
     
    procedure dfs_value(x,fa,lz:longint);
    var
        q, p                            :longint;
    begin
        inc(sum[lz mod 3]);
        q:=last[x];
        while q<>0 do
        begin
            p:=other[q];
            if (p=fa) or (ff[q]) then
            begin
                q:=pre[q];
                continue;
            end;
            dfs_value(p,x,lz+len[q]);
            q:=pre[q];
        end;
    end;
     
    procedure solve(u:longint);
    var
        i, q, p                         :longint;
         
    begin
        getroot(u);
        if top=1 then exit;
        fillchar(b,sizeof(b),0);
        b[3]:=1;
        top:=0;
        q:=last[root];
        while q<>0 do
        begin
            p:=other[q];
            if ff[q] then
            begin
                q:=pre[q];
                continue;
            end;
            fillchar(sum,sizeof(sum),0);
            dfs_value(p,root,len[q]);
            for i:=0 to 3 do ans:=ans+b[i]*sum[3-i];
            ans:=ans+sum[0]*b[0];
            for i:=0 to 3 do inc(b[i],sum[i]);
            q:=pre[q];
        end;
         
        q:=last[root];
        while q<>0 do
        begin
            p:=other[q];
            if ff[q] then
            begin
                q:=pre[q];
                continue;
            end;
            ff[q]:=true;
            ff[q xor 1]:=true;
            solve(p);
            q:=pre[q];
        end;
             
    end;
     
         
    procedure main;
    var
        i                               :longint;
        x, y, z                         :longint;
        ans1, ans2                      :longint;
        g                               :longint;
         
    begin
        read(n);
        l:=1;
        fillchar(b,sizeof(b),$ff);
        b[0]:=0;    
        for i:=1 to n-1 do
        begin
            read(x,y,z);
            z:=z mod 3;
            connect(x,y,z);
            connect(y,x,z);
        end;
        ans:=0;
        solve(1);
        ans1:=2*ans+n; ans2:=n*n;
        g:=gcd(ans1,ans2);
        writeln(ans1 div g,'/',ans2 div g);
    end;
     
    begin
        main;
    end.
  • 相关阅读:
    get与post区别
    移动应用专项测试的思路和方法
    一个完整的http请求响应过程
    Linux基础
    浏览器输入url按回车背后经历了哪些?
    三大浏览器(火狐-谷歌-IE浏览器)驱动版本下载
    boost-序列化
    HTTP 2.0
    http首部字段
    与http协作的web服务器
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3510030.html
Copyright © 2020-2023  润新知