zoukankan      html  css  js  c++  java
  • bzoj 2783 JLOI2012 树

    bzoj2783 JLOI2012 树

    Description

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

    Input

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

    Output

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

    参考了神犇的博客,可以用dfs加set过,这么打比某些方法要方便一些.我们记录下一条链的前缀和,把它放进set里面,对于当前搜到的点x,如果set里面有一个元素等于sum[x]-S,那么表示从根到x节点的和减去那个元素所对应的点的和就是S.开始的时候要加入元素0.

    代码如下

    #include <set>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    static const int maxm=1e6+10;
    
    multiset<int>Set;
    
    int fst[maxm],nxt[maxm],to[maxm],sum[maxm],val[maxm];
    int S,cnt,n,x,y,ans;
    
    void ins(int f,int t){
        nxt[++cnt]=fst[f];
        fst[f]=cnt;
        to[cnt]=t;
    }
    
    void dfs(int x){
        if(Set.find(sum[x]-S)!=Set.end())ans++;
        Set.insert(sum[x]);
        for(int u=fst[x];u;u=nxt[u]){
    		int v=to[u];
    		sum[v]=sum[x]+val[v];
    		dfs(v);
        }
        Set.erase(Set.find(sum[x]));
    }
    
    int main(){
        scanf("%d%d",&n,&S);
        for(int i=1;i<=n;i++)scanf("%d",&val[i]);
        for(int i=1;i<n;i++)
    		scanf("%d%d",&x,&y),ins(x,y);
        
        sum[1]=val[1];Set.insert(0);
    
        dfs(1);
    
        printf("%d
    ",ans);
        
        return 0;
    }
    

    点我进入AC通道

  • 相关阅读:
    SQL SERVER导入Excel csv
    微信付款码扫码枪支付
    idftp
    不正常地定义参数对象。提供了不一致或不完整的信息
    sql 日志文件截断收缩
    sql server 新语法 收藏
    SQL SERVER 2019新功能
    SQL SERVER 死锁
    rad 10.2
    TXMLDocument 创建空值节点不要缩写
  • 原文地址:https://www.cnblogs.com/Exbilar/p/6764435.html
Copyright © 2011-2022 走看看