BZOJ2783: [JLOI2012]树 dfs+set

2783: [JLOI2012]树

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 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

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 }

 

 

posted @ 2015-08-03 18:15  meekyan  阅读(225)  评论(0编辑  收藏  举报