luogu P3254 树 解题报告

题目描述

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

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

输出格式

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

输入输出样例

输入:
3 3
1 2 3
1 2
1 3
输出:
2

说明/提示

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

题解

这是个dd题!
要多dd就有多dd!
n方直接过不需要动脑子
关键点:
1.处理根节点
2.当前值大于s时break

代码

#include <iostream>
#include <cstdio>
#define ll long long
#define R register
using namespace std;
inline int read(){
    int x=0,f=1;char c=getchar();
    while (c>'9'||c<'0') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
const int maxn=1e5+5;       
int s,n,ans;
int a[maxn],fa[maxn];

void init(){
    n=read(),s=read();
    for (R int i(1);i<=n;++i) a[i]=read(),fa[i]=i;
    for (R int i(1),x,y;i<n;++i) x=read(),y=read(),fa[y]=x;
}
inline int getroot(int u){
    if (fa[u]==u) return u;
    return getroot(fa[u]);
}
void doit(){
    int rt=getroot(1);
    for (R int i(1);i<=n;++i){
        int sum=a[i];
        if (sum==s) ans++;
        if (sum>s) continue;
        int j=i;
        while (j!=rt){
            j=fa[j];
            sum+=a[j];
            if (sum==s) ++ans;
            if (sum>s) break;
        }
    }
    printf("%d\n",ans);
}
int main(){
    init();
    doit();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ancer/p/11316189.html