• poj1741 Tree


    终于不颓了今天

    点分。对于无根树上的路径,对于一个点(视作根)来说,要么这条路径是经过当前点,要么是存在于这个点的子树,后者交给子树做,对于前者,处理出树中所有点到达根的距离,以及存在于根的那个孩子的子树。按距离排一遍序,从大到小枚举点,同时指针从小到大枚举和它配对的点,由于枚举点的大小单调递减,所以指针前面的点肯定可以和当前点配对,从当前指针位置枚举即可。这样就相当于O(n)的复杂度。还有,要用数组+时间戳记录当前某个子树的点在指针前有多少个,记录答案的时候要去掉同一子树的配对情况。

    我TM的getrt完了之后为啥点分传的还是y

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    int n,K;
    struct node
    {
        int x,y,d,next;
    }a[21000];int len,last[11000];
    void ins(int x,int y,int d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }
    
    int rt,sum,tot[11000],G[11000];
    bool v[11000];
    void getrt(int x,int fr)
    {
        G[x]=0;tot[x]=1;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr&&v[y]==false)
            {
                getrt(y,x);
                G[x]=max(G[x],tot[y]);
                tot[x]+=tot[y];
            }
        }
        G[x]=max(G[x],sum-tot[x]);
        if(rt==0||G[rt]>G[x])rt=x;
    }
    
    //--------------------------
    
    struct zz{int bel,d;}z[11000];int zlen;
    bool cmp(zz z1,zz z2){return z1.d<z2.d;}
    void getd(int x,int fr,int bel,int d)
    {
        zlen++;
        z[zlen].bel=bel;z[zlen].d=d;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fr&&v[y]==false)getd(y,x,bel,d+a[k].d);
        }
    }
    int ap[11000],tim,ti[11000];
    int calc(int x)
    {
        zlen=0;
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(v[y]==false)getd(y,x,y,a[k].d);
        }
        sort(z+1,z+zlen+1,cmp);
        
        int be=1,ret=0; tim++;
        for(int i=zlen;i>=1;i--)
        {
            if(z[i].d<=K)ret++;
            for(int j=be;j<i;j++)
            {
                if(z[i].d+z[j].d<=K)
                {
                    if(ti[z[j].bel]!=tim){ti[z[j].bel]=tim;ap[z[j].bel]=0;}    
                    ap[z[j].bel]++;
                    be++;
                }
                else break;
            }
            if(i<be)ap[z[i].bel]--;
            ret+=min(i,be)-1-ap[z[i].bel];
        }
        return ret;
    }
    
    //---------------------------
    
    int ans;
    void divi(int x)
    {
        v[x]=true;ans+=calc(x);
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(v[y]==false)
            {
                rt=0;sum=tot[y];
                getrt(y,x);
                divi(rt);
            }
        }
    }
    
    
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        while(scanf("%d%d",&n,&K)!=EOF)
        {
            if(n==0&&K==0)break;
            
            len=0;memset(last,0,sizeof(last));
            int x,y,d;
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&x,&y,&d);
                ins(x,y,d);ins(y,x,d);
            }
            rt=0;sum=n;
            memset(v,false,sizeof(v));
            getrt(1,0);
            
            ans=0;
            tim=0;memset(ti,0,sizeof(ti));
            divi(rt);
            printf("%d
    ",ans);
        }
        return 0;
    }

     

  • 相关阅读:
    nodejs express hi-cms
    写让别人能读懂的代码
    统计学和数据挖掘的关系
    假设检验
    相关性探索
    领域驱动设计分层类图
    未能加载文件或程序集 Ninject.Web.Common, Version=3.2.0.0
    论文阅读笔记
    《Computational Statistics with Matlab》硬译2
    C#抽象类和接口
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9447083.html
Copyright © 2020-2023  润新知