题目描述
在这个问题中,给定一个值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;
}