zoukankan      html  css  js  c++  java
  • 「POJ 1741」Tree

    题面:

    Tree

    Give a tree with n vertices,each edge has a length(positive integer less than 1001).
    Define dist(u,v)=The min distance between node u and v.
    Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
    Write a program that will count how many pairs which are valid for a given tree.

    Input
    The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
    The last test case is followed by two zeros.

    Output
    For each test case output the answer on a single line.

    Sample Input

    5 4
    1 2 3
    1 3 1
    1 4 2
    3 5 1
    0 0

    Sample Output

    8

    题意:

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

    输入格式: 每次输入n,k(如果n0&&k0停止),接着n-1行,每行3个数描述边

    这道题就是一道淀粉质点分治的模板题,具体不多讲,如果不会看看这个

    接下来直接上代码

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=200001;
    int read() {
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9')c=='-'?f=-1,c=getchar():c=getchar();
        while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x*f;
    }
    int n,k;
    int dep[N];/*从当前节点i到枚举当前树的根节点父亲的距离*/
    int f[N];/*当i为根节点时最大字数大小*/
    int vis[N];/*i节点是否被当根使用过*/
    int siz[N];/*以i节点为根时,其子树(包括本身)的节点个数*/
    int root;/*根节点*/
    struct node {
        int next,to,v;
    } a[N<<1];
    int head[N],cnt,sum/*这棵当前递归的这棵树的大小*/;
    void add(int x,int y,int c) {
        a[++cnt].to=y;
        a[cnt].next=head[x];
        a[cnt].v=c;
        head[x]=cnt;
    }
    void findroot(int k,int fa) {
        f[k]=0,siz[k]=1;
        for(int i=head[k]; i; i=a[i].next) {
            int v=a[i].to;
            if(vis[v]||v==fa)
                continue;
            findroot(v,k);
            siz[k]+=siz[v];
            f[k]=max(f[k],siz[v]);
        }
        f[k]=max(f[k],sum-siz[k]);
        if(f[k]<f[root])
            root=k;
    }
    int tot;
    void finddep(int k,int fa,int l) {
        dep[++tot]=l;
        for(int i=head[k]; i; i=a[i].next) {
            int v=a[i].to;
            if(v==fa||vis[v])
                continue;
            finddep(v,k,l+a[i].v);
        }
    }
    int K;
    int calc(int k,int L) {
        tot=0;
        finddep(k,0,L);
        sort(dep+1,dep+1+tot);
        int l=1,r=tot,ans=0;
        while(l<r){
            if(dep[l]+dep[r]<=K)
                l++,ans+=r-l+1;
            else
                r--;
        }
        return ans;
    }
    int js;
    void devide(int k) {
        vis[k]=1;
        js+=calc(k,0);
        for(int i=head[k]; i; i=a[i].next) {
            int v=a[i].to;
            if(vis[v])
                continue;
            js-=calc(v,a[i].v);
            root=0,sum=siz[v];
            findroot(v,0);
            devide(root);
        }
    }
    int main() {
        int n=read(),x,y,z;
        K=read();
        while(n&&K){
            memset(head,0,sizeof(head)),cnt=0;//head
            memset(vis,0,sizeof(vis));//标记数组
            for (int i=1; i<n; i++)
                x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
            sum=f[0]=n,js=0;//总数
            findroot(1,0);
            devide(root);
            printf("%d
    ",js);
            n=read(),K=read();
        }
        return 0;
    }
    

    注意初始化!!!注意初始化!!!注意初始化!!!
    重要的事情说三遍

  • 相关阅读:
    关于i 标签盛放背景图像
    关于首行缩进
    复选框样式自定义
    创建对象的两种方法
    SpringBoot项目中常见的注解
    微服务 第一章:Idea快速创建SpringBoot项目
    Exception in thread "Thread-1" java.util.ConcurrentModificationException 异常原因和解决方法
    《改善java代码》第四章:改善关于字符串的代码
    IDEA忽略不必要提交的文件
    Git分支管理
  • 原文地址:https://www.cnblogs.com/hbxblog/p/9831365.html
Copyright © 2011-2022 走看看