zoukankan      html  css  js  c++  java
  • BZOJ1468 Tree

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1468

    一道水题,好久没有打点分治了有点手生。

    犯了傻,打错了 addedge 调了1h。

    基本思路就是按层分治,不超过 O(logn) 层,每一层 O(n) 或者 O(logn) 根据主定理 T(n) = T(n/2) + O(nlogn)

    复杂度 O(nlog^2n) 。

    此题在统计路径时还要注意容斥,要减去多余的路径。(具体看紫书即可)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    #define N 50010
    #define LL long long
    
    using namespace std;
    
    struct edge{
        int x,to,v;
    }E[N<<1];
    
    int n,g[N],K,totE,ansv;
    
    inline void addedge(int x,int y,int v){
        E[++totE]=(edge){y,g[x],v}; g[x]=totE;
        E[++totE]=(edge){x,g[y],v}; g[y]=totE;
    }
    
    #define p E[i].x
    
    namespace Tree_Dc{
        int siz[N],root,f[N],totn,a[N],d[N],tot;
        bool v[N];
        
        void Find_Hea(int x,int ft){
            siz[x]=1; f[x]=0;
            for(int i=g[x];i;i=E[i].to)
                if(ft!=p&&!v[p]){
                    Find_Hea(p,x);
                    siz[x]+=siz[p];
                    f[x]=max(f[x],siz[p]);
                }
            f[x]=max(f[x],totn-siz[x]);
            if(!root||f[x]<f[root])
                root=x;
        }
        
        inline int Root(int x){
            root=0; totn=siz[x];
            Find_Hea(x,x);
            return root;
        }
        
        void dfs(int x,int ft){
            a[++tot]=d[x];
            for(int i=g[x];i;i=E[i].to)
                if(!v[p]&&p!=ft){
                    d[p]=d[x]+E[i].v;
                    dfs(p,x);
                }
        }
        
        inline int count_path(int x,int v){
            d[x]=v; tot=0;
            dfs(x,0);
            sort(a+1,a+tot+1);
            int ans=0,tmp=1;
            for(int i=2;i<=tot;i++){
                while(tmp<i&&a[i]+a[tmp+1]<=K) tmp++;
                while(tmp&&a[i]+a[tmp]>K) tmp--;
                ans+=min(tmp,i-1);
            }
            return ans;
        }
        
        void DC(int x){
            int tmp=ansv;
            ansv+=count_path(x,0);
            v[x]=1;
            for(int i=g[x];i;i=E[i].to)
                if(!v[p]){
                    ansv-=count_path(p,E[i].v);
                    DC(Root(p));
                }
        }
    }
    
    int main(){
        freopen("test.in","r",stdin);
        scanf("%d",&n);
        for(int i=1,x,y,v;i<n;i++){
            scanf("%d%d%d",&x,&y,&v);
            addedge(x,y,v);
        }
        scanf("%d",&K);
        Tree_Dc::siz[1]=n;
        Tree_Dc::DC(Tree_Dc::Root(1));
        printf("%d
    ",ansv);
        return 0;
    }
    Code
  • 相关阅读:
    MySQL锁系列3 MDL锁
    MySQL锁系列2 表锁
    MySQL锁系列1
    MySQL open table
    MySQL优化器join顺序
    MySQL优化器cost计算
    MySQL源码 优化器
    MySQL源码 解析器
    MySQL源码 数据结构hash
    微信小程序爬坑日记
  • 原文地址:https://www.cnblogs.com/lawyer/p/4549261.html
Copyright © 2011-2022 走看看