博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj2783 [JLOI2012]树
阅读量:5235 次
发布时间:2019-06-14

本文共 1542 字,大约阅读时间需要 5 分钟。

[JLOI2012]树

Time Limit: 1 Sec Memory Limit: 128 MB

Description

在这个问题中,给定一个值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一次,然后每次dfs到一个点的时候算一下以这个点结尾的答案。
所以你要手写一个类似队列的东西,一个头指针一个尾指针。
然后让队列里的东西和是最靠近 s 的。
这个维护要注意一下细节就好了。
复杂度应该很快。。。只是我不会算而已QAQ

#include
using namespace std;const int maxn = 1e5 + 5;int ans, op = 1, ed, all, n, s, data[maxn];int ini[maxn];vector
point[maxn];inline void read(int &x){ x = 0; static char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)){x = x * 10 + c - '0'; c = getchar();}}void dfs(int t, int step){ ini[step] = data[t]; ed = step; int lin = op, la = all; all += data[t]; while(all > s && op < ed){all -= ini[op]; op++;} while(op > 1 && all + ini[op] < s){op--; all += ini[op];} if(all == s) ans++; for(int i = point[t].size() - 1; i >= 0; --i) dfs(point[t][i], step + 1); all -= ini[step]; ed = step - 1; op = lin; all = la;}int main(){// freopen("lpl.in", "r", stdin); read(n); read(s); for(int i = 1; i <= n; ++i) read(data[i]); for(int a, b, i = 1; i < n; ++i){ read(a); read(b); point[a].push_back(b); } dfs(1, 1); cout << ans; return 0;}

转载于:https://www.cnblogs.com/LLppdd/p/9892813.html

你可能感兴趣的文章
苹果开发者账号那些事儿(二)
查看>>
使用C#交互快速生成代码!
查看>>
UVA11374 Airport Express
查看>>
P1373 小a和uim之大逃离 四维dp,维护差值
查看>>
NOIP2015 运输计划 树上差分+树剖
查看>>
P3950 部落冲突 树链剖分
查看>>
读书_2019年
查看>>
读书汇总贴
查看>>
微信小程序 movable-view组件应用:可拖动悬浮框_返回首页
查看>>
MPT树详解
查看>>
空间分析开源库GEOS
查看>>
RQNOJ八月赛
查看>>
前端各种mate积累
查看>>
jQuery 1.7 发布了
查看>>
Python(软件目录结构规范)
查看>>
Windows多线程入门のCreateThread与_beginthreadex本质区别(转)
查看>>
Nginx配置文件(nginx.conf)配置详解1
查看>>
linux php编译安装
查看>>
name phone email正则表达式
查看>>
721. Accounts Merge
查看>>