zoukankan      html  css  js  c++  java
  • BZOJ1468Tree——点分治

    题目描述

    给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K

    输入

    N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是k

    输出

    一行,有多少对点之间的距离小于等于k

    样例输入

    7
    1 6 13
    6 3 9
    3 5 7
    4 1 3
    2 4 20
    4 7 2
    10

    样例输出

    5
     
    点分治模板题,因为统计答案满足逆运算,所以可以用单步容斥来统计,将“任意两个子节点路径<=k的方案数”-“在同一子树内两节点路径<=k的方案数”就是最终答案。
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,k;
    int tot;
    int num;
    int cnt;
    int ans;
    int root;
    int x,y,z;
    int s[80000];
    int to[160000];
    int mx[80000];
    int val[160000];
    int head[80000];
    int next[160000];
    int size[80000];
    bool vis[80000];
    void add(int x,int y,int v)
    {
        tot++;
        next[tot]=head[x];
        head[x]=tot;
        to[tot]=y;
        val[tot]=v;
        tot++;
        next[tot]=head[y];
        head[y]=tot;
        to[tot]=x;
        val[tot]=v;
    }
    void getroot(int x,int fa)
    {
        size[x]=1;
        mx[x]=0;
        for(int i=head[x];i;i=next[i])
        {
            if(to[i]!=fa&&!vis[to[i]])
            {
                getroot(to[i],x);
                size[x]+=size[to[i]];
                mx[x]=max(mx[x],size[to[i]]);
            }
        }
        mx[x]=max(mx[x],num-size[x]);
        if(!root||mx[x]<mx[root])
        {
            root=x;
        }
    }
    void dfs(int x,int fa,int dis)
    {
        s[cnt++]=dis;
        for(int i=head[x];i;i=next[i])
        {
            if(to[i]!=fa&&!vis[to[i]])
            {
                dfs(to[i],x,dis+val[i]);
            }
        }
    }
    int calc(int x,int v)
    {
        int ans=0;
        cnt=0;
        dfs(x,0,v);
        sort(s,s+cnt);
        for(int l=0,r=cnt-1;l<r;l++)
        {
            while(s[l]+s[r]>k&&l<r)
            {
                r--;
            }
            ans+=r-l;
        }
        return ans;
    }
    void partition(int x)
    {
        vis[x]=1;
        ans+=calc(x,0);
        for(int i=head[x];i;i=next[i])
        {
            if(!vis[to[i]])
            {
                ans-=calc(to[i],val[i]);
                num=size[to[i]];
                root=0;
                getroot(to[i],0);
                partition(root);
            }
        }
    }
    int main()
    {   
        mx[0]=2147483647;
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        scanf("%d",&k);
        getroot(1,0);
        partition(root);
        printf("%d",ans);
    }
  • 相关阅读:
    示例 json with js
    JS json
    jquery
    发布包规范
    20180320待编辑
    CefSharp中c#和js交互
    列举mvc ActionResult的返回值
    怎么实现第三方登录
    mvc @Html控件
    MVC webuploader 图片
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9182483.html
Copyright © 2011-2022 走看看