zoukankan      html  css  js  c++  java
  • BZOJ 1468——tree

    BZOJ 1468——tree

    点分治思想,处理一些树上路径问题中的高效算法。

    重心——作用是可以优化时间复杂度,使递归的层数最少。

    重心就是以某个点为根且这个点的子树最大值是最小的。

    找重心的基本思路:

    dfs求得每一个点的最大子树Maxsize,用数组记录下来,

    判断这个值是否比当前根的Maxsize小。每次找重心都会更新size数组。

    inline void getroot(int x,int fa){
        size[x]=1;Maxsize[x]=0;
        for(int i=head[x];i;i=e[i].next){
            if(!vis[e[i].to]&&e[i].to!=fa){
                getroot(e[i].to,x);size[x]+=size[e[i].to];Maxsize[x]=max(Maxsize[x],size[e[i].to]);
            }
        }
        Maxsize[x]=max(Maxsize[x],temp-size[x]);
        if(Maxsize[x]<Maxsize[root]) root=x;
    }
    getroot

    找重心

    处理计算通过根节点的路径。

    递归处理每个根节点的子节点。重复以上操作

    Notice:在计算通过某个点的个数时,还需要减去一些不符合题意的边,

    就是没有通过当前节点的边,才不会重复计算。

    每次计算完一个节点后,把该节点删去,即用vis标记。

    此外,用一个deep数组来储存以X节点为根时,该节点的子树中到根的距离。(代码中的deep[0]只是一个计数变量而已)

    #include<cstdio>
    #include<algorithm>
    #define maxn 40010
    using namespace std;
    struct LINK{
        int to,next,v;
    }e[maxn*2];
    int deep[maxn],Distance[maxn],Maxsize[maxn],size[maxn],temp,tot,head[maxn],vis[maxn],root,k,ans;
    inline char Getchar(){
        static char BUF[16384],*S=BUF,*T=BUF;
        return(S==T)&&(T=(S=BUF)+fread(BUF,1,16384,stdin),S==T)?EOF:*S++;
    }
    inline int read(){
        int w=0;char c=Getchar();
        while(c<'0'||c>'9') c=Getchar();
        while(c>='0'&&c<='9'){
            w=w*10+c-48;
            c=Getchar();
        }
        return w;
    }
    inline void add(int x,int y,int w){
        tot++;
        e[tot].to=y;
        e[tot].next=head[x];
        e[tot].v=w;
        head[x]=tot;
    }
    inline void getroot(int x,int fa){
        size[x]=1;Maxsize[x]=0;
        for(int i=head[x];i;i=e[i].next){
            if(!vis[e[i].to]&&e[i].to!=fa){
                getroot(e[i].to,x);size[x]+=size[e[i].to];Maxsize[x]=max(Maxsize[x],size[e[i].to]);
            }
        }
        Maxsize[x]=max(Maxsize[x],temp-size[x]);
        if(Maxsize[x]<Maxsize[root]) root=x;
    }
    inline void getdeep(int x,int fa){
        deep[++deep[0]]=Distance[x];
        for(int i=head[x];i;i=e[i].next){
            if(!vis[e[i].to]&&e[i].to!=fa){
                Distance[e[i].to]=Distance[x]+e[i].v;getdeep(e[i].to,x);
            }
        }
    }
    inline int answer(int x,int w){
        int ans=0,l=1,r;
        Distance[x]=w;deep[0]=0;getdeep(x,0);
        sort(deep+1,deep+deep[0]+1);
        r=deep[0];
        while(l<r){
            if((deep[l]+deep[r])<=k) ans+=r-l,l++;
            else r--;    
        }
        return ans;
    }
    inline void solve(int x){
        ans+=answer(x,0);vis[x]=1;
        for(int i=head[x];i;i=e[i].next){
            if(!vis[e[i].to]){
                ans-=answer(e[i].to,e[i].v);temp=size[e[i].to];root=0;
                getroot(e[i].to,0);solve(root);
            }
        }
    }
    int main(){
        int n,i,x,y,v;
        n=read();
        for(i=1;i<n;i++){
            x=read();y=read();v=read();
            add(x,y,v);add(y,x,v);
        }
        k=read();Maxsize[0]=n+1;
        temp=n;
        getroot(1,0);solve(root);
        printf("%d",ans);
    }
    BZOJ 1468 tree

     

  • 相关阅读:
    安装Linux Mint 17后要做的20件事
    通过HttpURLConnection 上传和下载文件(二)
    Apache Solr入门教程(初学者之旅)
    厉害了,利用深度学习开发人脸识别老板探测器(附源码)
    Solr教程--官方自带数据的三个练习及讨论翻译版本
    solr启动时报错org.apache.solr.common.SolrException: undefined field text的解决办法
    Qt项目里的源代码默认都是Unicode,原因大概是因为qmake.conf里的定义
    How to Capture the Integer-Divide-By-Zero Error in C++(提前定义信号)
    Model-View-Controller Explained in C++
    How to Use the Dynamic Link Library in C++ Linux (C++调用Delphi写的.so文件)
  • 原文地址:https://www.cnblogs.com/Fish-/p/8275743.html
Copyright © 2011-2022 走看看