zoukankan      html  css  js  c++  java
  • 【POJ1741】Tree 树分而治之 模板略?

    做广告:

    #include <stdio.h>
    int main()
    {
        puts("转载请注明出处[vmurder]谢谢");
        puts("网址:blog.csdn.net/vmurder/article/details/44302921");
    }

    题意:

    给你一棵无根树,求有多少点对之间距离<=K。

    题解:

    树分治。
    然后对于一个重心X。我们把它的全部子树中的全部点存到结构体数组中。
    结构体中存距离和子树编号。
    第一遍sort,我们双指针扫哪些点对符合要求。
    第二遍sort,我们把同一子树中还符合要求的点对数目删掉。
    sort是O(nlogn)。处理是O(n)
    然后分治logn层,总时间复杂度O(nlog2n)

    代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 50100
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,m;
    struct Eli
    {
        int v,len,next;
    }e[N<<1];
    int head[N],cnt;
    bool rem[N];
    inline void add(int u,int v,int len)
    {
        e[++cnt].v=v;
        e[cnt].len=len;
        e[cnt].next=head[u];
        head[u]=cnt;
    }
    int f[N],f2[N],son[N];
    int TreeCenter,length;
    int dfs1(int x,int p)
    {
        int i,v;
        f[x]=f2[x]=0;
        for(i=head[x];i;i=e[i].next)
        {
            v=e[i].v;
            if(v==p||rem[v])continue;
            int temp=dfs1(v,x);
            if(temp>f[x])
            {
                f2[x]=f[x];
                f[x]=temp;
                son[x]=v;
            }
            else if(temp>f2[x])
                f2[x]=temp;
        }
        return f[x]+1;
    }
    int g[N];
    void dfs2(int x,int p)
    {
        int i,v;
        if(max(f[x],g[x])<length)
        {
            length=max(f[x],g[x]);
            TreeCenter=x;
        }
        for(i=head[x];i;i=e[i].next)
        {
            v=e[i].v;
            if(v==p||rem[v])continue;
            if(v==son[x])g[v]=max(g[x],f2[x])+1;
            else g[v]=max(g[x],f[x])+1;
            dfs2(v,x);
        }
        return ;
    }
    inline int get_TreeCenter(int x)
    {
        if(rem[x])return 0;
        length=inf,g[x]=0;
        dfs1(x,0),dfs2(x,0);
        return TreeCenter;
    }
    struct Summorer
    {
        int a,b;
        // 权值,子树标号
        Summorer(int _a=0,int _b=0):a(_a),b(_b){}
    }src[N];
    inline int cmpa(Summorer a,Summorer b)
    {
        return a.a<b.a;
    }
    inline int cmpb(Summorer a,Summorer b)
    {
        return a.b==b.b?

    a.a<b.a:a.b<b.b; } int size[N]; void dfs3(int x,int p,int t,int len) { src[++cnt]=Summorer(len,t); size[x]=1; int i,v; for(i=head[x];i;i=e[i].next) { v=e[i].v; if(rem[v]||v==p)continue; dfs3(v,x,t,len+e[i].len); size[x]+=size[v]; } return ; } int ans; void work(int x,int n) { if(!n)return ; rem[x=get_TreeCenter(x)]=1; int num=0,i,j,k,v,p; cnt=0; for(i=head[x];i;i=e[i].next) { v=e[i].v; if(rem[v])continue; dfs3(v,x,++num,e[i].len); } sort(src+1,src+cnt+1,cmpa); p=n; for(i=0;i<=n;i++) { while(i<p&&src[i].a+src[p].a>m)p--; if(i>=p)break; ans+=(p-i); } sort(src+1,src+cnt+1,cmpb); src[cnt+1].b=-1; for(i=0;i<=n;i=j) { for(j=i+1;src[j].b==src[i].b;j++); for(p=j-1,k=i;k<j;k++) { while(k<p&&src[k].a+src[p].a>m)p--; if(k>=p)break; ans-=(p-k); } } for(i=head[x];i;i=e[i].next) { v=e[i].v; if(rem[v])continue; work(v,size[v]-1); } return ; } void init() { ans=cnt=0; memset(rem,0,sizeof rem); memset(head,0,sizeof head); } int main() { int i,a,b,c; while(scanf("%d%d",&n,&m),(n|m)) { init(); for(i=1;i<n;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c),add(b,a,c); } work(1,n-1); printf("%d ",ans); } return 0; }

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    iOS6后的内存警告处理
    key things of ARC
    敏捷软件开发Note
    ViewController的属性
    sizeToFit & sizeThatFits
    iOS静态库的制作与引用
    xcode添加build phase
    什么是HUD
    xcode中的预定义宏
    管理授权&管理决策&管理组织&管理目标
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4890119.html
Copyright © 2011-2022 走看看