在這個問題中,給定一個值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
對於30%數據,N≤100;
對於60%數據,N≤1000;
對於100%數據,N≤100000,所有權值以及S都不超過1000。
一開始想了很多種奇妙的方法,最後發現自己都無法很完美地實現,最後無奈之下打個暴力想騙分,結果A了!(數據過水?)
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int N, t;
int havefa[100005], h[100005], A[100005];
long long Ans, S;
struct node
{
int to, next;
}F[100005];
void dfs(int x, long long dep)
{
dep += A[x];//一直疊加路徑總值
if (dep == S) {
Ans++;
return;
}//達到了就給路徑數加上
else if (dep > S) return;//如果超過了目標值也就沒有繼續搜下去的必要了
else {
for (int i = h[x]; i; i = F[i].next)
dfs(F[i].to, dep);
}
}
int main()
{
scanf("%d%lld", &N, &S);
for (int i = 1; i <= N; ++i)
scanf("%d", &A[i]);
for (int i = 1; i < N; ++i)
{
int x, y;
scanf("%d%d", &x, &y);
F[++t] = (node){y, h[x]}; h[x] = t;
havefa[y] = 1;
}
for (int i = 1; i <= N; ++i) dfs(i, 0);
printf("%lld", Ans);
return 0;
}