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 }
时间: 2024-08-04 10:16:21

BZOJ2783: [JLOI2012]树 dfs+set的相关文章

【BZOJ2783】[JLOI2012]树 DFS+栈+队列

[BZOJ2783][JLOI2012]树 Description 在这个问题中,给定一个值S和一棵树.在树的每个节点有一个正整数,问有多少条路径的节点总和达到S.路径中节点的深度必须是升序的.假设节点1是根节点,根的深度是0,它的儿子节点的深度为1.路径不必一定从根节点开始. Input 第一行是两个整数N和S,其中N是树的节点数. 第二行是N个正整数,第i个整数表示节点i的正整数. 接下来的N-1行每行是2个整数x和y,表示y是x的儿子. Output 输出路径节点总和为S的路径数量. Sa

[bzoj2783][JLOI2012]树_树的遍历

树 bzoj2783 JLOI2012 题目大意:给定一棵n个点的树.求满足条件的路径条数.说一个路径是满足条件的,当且仅当这条路径上每个节点深度依次递增且点权和为S. 注释:$1\le n\le 10^5$,$1\le S,val_i\le 10^3$. 想法:翻lijinnn的blog翻到的水题. 我们直接遍历整棵树,遍历的时候维护全局桶.然后在回溯的时候将这个点对应的dis删除.这样遍历到每个点时桶内对应的就是这个点到根节点的dis桶,直接统计答案即可. 最后,附上丑陋的代码... ...

2783: [JLOI2012]树( dfs + BST )

直接DFS, 然后用set维护一下就好了.... O(nlogn) -------------------------------------------------------------------------------- #include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; ++i) #define clr(x, c) memset(x, c, sizeof(x)) #define foreach(i, x

bzoj2783: [JLOI2012]树

2783: [JLOI2012]树 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 447[Submit][Status][Discuss] Description 数列 提交文件:sequence.pas/c/cpp 输入文件:sequence.in 输出文件:sequence.out 问题描述: 把一个正整数分成一列连续的正整数之和.这个数列必须包含至少两个正整数.你需要求出这个数列的最小长度.如果这个数列不存在则输出-

【dfs】【哈希表】bzoj2783 [JLOI2012]树

因为所有点权都是正的,所以对每个结点u来说,每条从根到它的路径上只有最多一个结点v符合d(u,v)=S. 所以我们可以边dfs边把每个结点的前缀和pre[u]存到一个数据结构里面,同时查询pre[u]-S是否存在. 数据结构用set.hashtable(随便卡)(需要支持删除,由于总是删掉最后一个,因此可以实现)都行. #include<cstdio> #include<cstring> using namespace std; #define MAXN 100001 #defin

BZOJ 2783 JLOI2012 树 DFS

题目大意:给定一棵有根树,每个节点有权值,求有多少链上的权值和为S,要求链上节点的深度必须单调(即这条链由某个节点出发指向根) DFS一遍,当深搜到一个点时将这个点加入队列,同时队头向后调整,使队列中元素之和<=s,记录ans 当一个点出栈时将队尾删除,同时队头向前调整,使队列中元素之和刚好<=s 这题1s略卡时间...不过我旁边的哥们用nlogn的算法超时700ms过去的0.0 这怎么过去的0.0 误差也太大了吧0.0 #include<cstdio> #include<c

洛谷 P3252 [JLOI2012]树

P3252 [JLOI2012]树 题目描述 在这个问题中,给定一个值S和一棵树.在树的每个节点有一个正整数,问有多少条路径的节点总和达到S.路径中节点的深度必须是升序的.假设节点1是根节点,根的深度是0,它的儿子节点的深度为1.路径不必一定从根节点开始. 输入输出格式 输入格式: 第一行是两个整数N和S,其中N是树的节点数. 第二行是N个正整数,第i个整数表示节点i的正整数. 接下来的N-1行每行是2个整数x和y,表示y是x的儿子. 输出格式: 输出路径节点总和为S的路径数量. 输入输出样例

题解 P3252 【[JLOI2012]树】

\(\Huge{[JLOI2012]树}\) 题目描述 在这个问题中,给定一个值S和一棵树.在树的每个节点有一个正整数,问有多少条路径的节点总和达到S.路径中节点的深度必须是升序的.假设节点1是根节点,根的深度是0,它的儿子节点的深度为1.路径不必一定从根节点开始. 输入输出格式 输入格式: 第一行是两个整数N和S,其中N是树的节点数. 第二行是N个正整数,第i个整数表示节点i的正整数. 接下来的N-1行每行是2个整数x和y,表示y是x的儿子. 输出格式: 输出路径节点总和为S的路径数量. 输入

HDU 5692 线段树+dfs序

Snacks Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1779    Accepted Submission(s): 427 Problem Description 百度科技园内有n 个零食机,零食机之间通过n−1 条路相互连通.每个零食机都有一个值v ,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v