• 【BZOJ-1468】Tree 树分治


    1468: Tree

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 1025  Solved: 534
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

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

    Sample Output

    5

    HINT

    Source

    LTC男人八题系列

    Solution

    写LTC还不如直接写ACRush,楼教主的男人八题.暑假看过什么都看不懂,现在似乎可以做了?

    裸的树分治,统计一下路径的权值和,排序计算答案即可

    Code

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 80010
    int n,root,siz,ans,stack[maxn],top,K;
    struct Edgenode{int to,next,val;}edge[maxn<<1];
    int head[maxn],cnt=1;
    void add(int u,int v,int w)
    {cnt++; edge[cnt].val=w; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt;}
    void insert(int u,int v,int w)
    {add(u,v,w);add(v,u,w);}
    int gcd(int a,int b)
    {if (b==0) return a; return gcd(b,a%b);}
    int size[maxn],maxx[maxn],val[maxn]; bool visit[maxn];
    void DFSroot(int now,int last)
    {
        size[now]=1; maxx[now]=0;
        for (int i=head[now]; i; i=edge[i].next)
            if (edge[i].to!=last && !visit[edge[i].to])
                {
                    DFSroot(edge[i].to,now);
                    size[now]+=size[edge[i].to];
                    maxx[now]=max(maxx[now],size[edge[i].to]);
                }
        maxx[now]=max(maxx[now],siz-size[now]);
        if (maxx[now]<maxx[root]) root=now;
    }
    void DFSval(int now,int last)
    {
        stack[++top]=val[now];
        for (int i=head[now]; i; i=edge[i].next)
            if (edge[i].to!=last && !visit[edge[i].to])
                {    
                    val[edge[i].to]=val[now]+edge[i].val;
                    DFSval(edge[i].to,now);
                }
    }
    int Getans(int now,int va)
    {
        val[now]=va; top=0; DFSval(now,0);
        sort(stack+1,stack+top+1);
        int re=0,l=1,r=top;
        while (l<r) if (stack[l]+stack[r]<=K) re+=r-l,l++; else r--;
        return re;
    }
    void work(int now)
    {
        ans+=Getans(now,0);
        visit[now]=1;
        for (int i=head[now]; i; i=edge[i].next)
            if (!visit[edge[i].to])
                {
                    ans-=Getans(edge[i].to,edge[i].val);
                    root=0; siz=size[edge[i].to];
                    DFSroot(edge[i].to,0); work(root);
                }
    }
    int main()
    {
        n=read();
        for (int u,v,w,i=1; i<=n-1; i++) 
            u=read(),v=read(),w=read(),insert(u,v,w);
        K=read();
        maxx[0]=siz=n;
        DFSroot(1,0);
        work(root);
        printf("%d
    ",ans);
        return 0;
    }

    吃饭前想10分钟Rush出来...手速不够TAT

  • 相关阅读:
    JS事件
    BOM
    DOM
    常见的SQL字符串函数
    常用的认证方式
    后台代码扫描规则-sonarQube官方
    spring cloud中feign的使用
    常见基于 REST API 认证方式
    Java中连接池
    这是一张心情贴
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5471182.html
Copyright © 2020-2023  润新知