zoukankan      html  css  js  c++  java
  • 洛谷 P3252 [JLOI2012]树

    题目描述

    在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。

    输入输出格式

    输入格式:

     

    第一行是两个整数N和S,其中N是树的节点数。 第二行是N个正整数,第i个整数表示节点i的正整数。 接下来的N-1行每行是2个整数x和y,表示y是x的儿子。

     

    输出格式:

     

    输出路径节点总和为S的路径数量。

     

    输入输出样例

    输入样例#1:
    3 3
    1 2 3
    1 2
    1 3
    输出样例#1:
    2

    说明

    对于100%数据,N<=100000,所有权值以及S都不超过1000。

    思路:树上前缀和或者是爆搜

    #include<iostream>
    #include<set>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MAXN 100100
    using namespace std;
    set<int>se;
    int n,s,tot,ans;
    int sum[MAXN],w[MAXN],dad[MAXN];
    int to[MAXN*2],head[MAXN*2],net[MAXN*2];
    void add(int u,int v){
        to[++tot]=v;net[tot]=head[u];head[u]=tot;
    }
    void dfs(int now){
        sum[now]=sum[dad[now]]+w[now];
        se.insert(sum[now]);
        if(se.find(sum[now]-s)!=se.end())    ans++;
        for(int i=head[now];i;i=net[i])    dfs(to[i]);
        se.erase(sum[now]);
    }
    int main(){
        scanf("%d%d",&n,&s);
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]);
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            dad[y]=x;
            add(x,y);
        }
        se.insert(0);
        dfs(1);
        cout<<ans;
    }
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    线程交互
    线程死锁
    多线程的同步-sychronized
    线程常见方法
    创建多线程
    消费!
    Redis基本认识
    在右键菜单中加入"在IDEA中打开" (Open in IDEA)
    安装coc.nvim时 报[coc.nvim] javascript file not found 错误的解决方案
    汇编语言的种类
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7465175.html
Copyright © 2011-2022 走看看