题意:给出一个有根树,点上有点权,求点权和为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 }