1. 程式人生 > >[bzoj2783] 樹

[bzoj2783] 樹

tchar 刪除 處理 bzoj2783 之前 erase return ios etc

題意:給出一個有根樹,點上有點權,求點權和為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 }

[bzoj2783] 樹