原以为要链剖什么的 然后。。
直接dfs用set维护前缀和 注意初始化insert(0)(为了保证根节点可取)
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<ctime> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #include<set> 9 #include<vector> 10 #define clr(a,x) memset(a,x,sizeof(a)) 11 #define rep(i,l,r) for(int i=l;i<r;i++) 12 typedef long long ll; 13 using namespace std; 14 int read() 15 { 16 char c=getchar(); 17 int ans1=0,f=1; 18 while(!isdigit(c)){ 19 if(c=='-') f=-1; 20 c=getchar(); 21 } 22 while(isdigit(c)){ 23 ans1=ans1*10+c-'0'; 24 c=getchar(); 25 } 26 return ans1*f; 27 } 28 const int maxn=100009; 29 int n,k,ans,sum[maxn],a[maxn]; 30 set<int>S; 31 vector<int>e[maxn]; 32 void dfs(int x) 33 { 34 if(S.find(sum[x]-k)!=S.end()) ++ans; 35 S.insert(sum[x]); 36 rep(i,0,e[x].size()){ 37 sum[e[x][i]]=sum[x]+a[e[x][i]]; 38 dfs(e[x][i]); 39 } 40 S.erase(S.find(sum[x])); 41 } 42 int main() 43 { 44 n=read(),k=read(); 45 rep(i,1,n+1) a[i]=read(); 46 rep(i,1,n){ 47 int from=read(),to=read(); 48 e[from].push_back(to); 49 } 50 sum[1]=a[1]; 51 S.insert(0); 52 dfs(1); 53 printf("%d\n",ans); 54 return 0; 55 }
2783: [JLOI2012]树
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 573 Solved: 343
[ Submit][ Status][ Discuss]
Description
第一行是两个整数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。
这个是JLOI2012的T1,发出来仅为了试题完整
=============================================================================================
在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。
Input
第一行是两个整数N和S,其中N是树的节点数。
第二行是N个正整数,第i个整数表示节点i的正整数。
接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
Output
输出路径节点总和为S的路径数量。
Sample Input
1 2 3
1 2
1 3
Sample Output
HINT
对于100%数据,N≤100000,所有权值以及S都不超过1000。