[bzoj2783] 树

题意:给出一个有根树,点上有点权,求点权和为s的路径数,路径上的点的深度要求递增

题解:

这题算比较水了,在树上用set维护一下权值和就可以了

用set维护的好处就是,可以实时维护路径和(加入一个值后可以很方便的删除),不会重复更新答案,之前写了个预处理前缀和的,会算重额

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<set>
 8 #define ll long long
 9 #define N 100010
10 using namespace std;
11 
12 int n,s,e_num,ans;
13 int nxt[N*2],to[N*2],h[N],sum[N],val[N];
14 
15 set<int> st;
16 
17 int gi() {
18   int x=0,o=1; char ch=getchar();
19   while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
20   if(ch=='-') o=-1,ch=getchar();
21   while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
22   return o*x;
23 }
24 
25 void add(int x, int y) {
26   nxt[++e_num]=h[x],to[e_num]=y,h[x]=e_num;
27 }
28 
29 void dfs(int u) {
30   if(st.find(sum[u]-s)!=st.end()) ans++;
31   st.insert(sum[u]);
32   for(int i=h[u]; i; i=nxt[i]) {
33     int v=to[i];
34     sum[v]=sum[u]+val[v];
35     dfs(v);
36   }
37   st.erase(st.find(sum[u]));
38 }
39 
40 int main() {
41   n=gi(),s=gi();
42   for(int i=1; i<=n; i++) val[i]=gi();
43   for(int i=1; i<n; i++) {
44     int x=gi(),y=gi();
45     add(x,y);
46   }
47   st.insert(0),sum[1]=val[1];
48   dfs(1);
49   printf("%d", ans);
50   return 0;
51 }
原文地址:https://www.cnblogs.com/HLXZZ/p/7611822.html