BZOJ2783: [JLOI2012]树 dfs+set
2783: [JLOI2012]树
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 588 Solved: 347
Description
数列
提交文件:sequence.pas/c/cpp
输入文件:sequence.in
输出文件:sequence.out
问题描述:
把一个正整数分成一列连续的正整数之和。这个数列必须包含至少两个正整数。你需要求出这个数列的最小长度。如果这个数列不存在则输出-1。
输入格式:
每行包含一个正整数n。
每个文件包含多行,读入直到文件结束。
输出格式:
对于每个n,输出一行,为这个数列的最小长度。
第一行是两个整数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。
数据范围:
对于所有数据,n≤263。
这个是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
3 3
1 2 3
1 2
1 3
1 2 3
1 2
1 3
Sample Output
2
HINT
对于100%数据,N≤100000,所有权值以及S都不超过1000。
题解
邻接表存图,dfs查找路径,set记录可能的路径s' 值
代码
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <ctime> 5 #include <iostream> 6 #include <algorithm> 7 #include <set> 8 #include <vector> 9 #include <queue> 10 #include <typeinfo> 11 #include <map> 12 #include <stack> 13 typedef long long ll; 14 using namespace std; 15 inline ll read() 16 { 17 ll x=0,f=1; 18 char ch=getchar(); 19 while(ch<'0'||ch>'9') 20 { 21 if(ch=='-')f=-1; 22 ch=getchar(); 23 } 24 while(ch>='0'&&ch<='9') 25 { 26 x=x*10+ch-'0'; 27 ch=getchar(); 28 } 29 return x*f; 30 } 31 //************************************************************************************** 32 33 set<int > s; 34 int t; 35 int n,sum; 36 struct ss 37 { 38 int to,next; 39 }e[101000]; 40 int sss; 41 int k,ans; 42 int head[101000]; 43 int a[101000]; 44 void init() 45 { 46 t=1; 47 memset(head,0,sizeof(head)); 48 } 49 void add(int u,int v) 50 { 51 e[t].to=v; 52 e[t].next=head[u]; 53 head[u]=t++; 54 } 55 void dfs(int x,int sum) 56 { 57 sum+=a[x]; 58 if(s.count(sum-sss))ans++; 59 s.insert(sum); 60 for(int i=head[x];i;i=e[i].next) 61 { 62 dfs(e[i].to,sum); 63 } 64 s.erase(sum); 65 } 66 int hash[100005]; 67 int main() 68 { 69 scanf("%d%d",&n,&sss); 70 init(); 71 for(int i=1;i<=n;i++) 72 { 73 scanf("%d",&a[i]); 74 } 75 int x,y; 76 for(int i=1;i<n;i++) 77 { 78 scanf("%d%d",&x,&y); 79 add(x,y); 80 hash[y]=1; 81 } 82 for(int i=1;i<=n;i++) 83 if(!hash[i]){k=i;break;} 84 s.clear(); 85 s.insert(0); 86 ans=0; 87 sum=0; 88 dfs(k,0); 89 90 cout<<ans<<endl; 91 return 0; 92 }