• [洛谷P3252] [JLOI2012] 树


    [洛谷P3252] [JLOI2012] 树

    给定一个值(S)和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到(S)
     路径中节点的深度必须是升序的。假设节点(1)是根节点,根的深度是(0),它的儿子节点的深度为(1)
     路径不必一定从根节点开始。

    Input

    第一行是两个整数(N)(S),其中(N)是树的节点数。
     第二行是(N)个正整数,第(i)个整数表示节点(i)的正整数。
     接下来的(N-1)行每行是(2)个整数(x)(y),表示(y)(x)的儿子。

    Output

    输出路径节点总和为(S)的路径数量。

    Example

    输入 #1

    (3) (3)
    (1) (2) (3)
    (1) (2)
    (1) (3)

    输出 #1

    (2)

    Scoring

    对于(100%)数据,(N≤100000),所有权值以及(S)都不超过(1000)

    注意:是总和刚好为(S),不是(≥S)

    刚开始审题看成(≥S)了orz

    咱也不会啥高端做法,暴力。

    盲猜权值无负数,这样的话选一个点,往下搜,搜到大于(S)就return,刚好等于(S)就ans++

    原本的错误想法:期望复杂度(O(nlogn)),数据很水,没有链,不会卡成(O(n^2))

    更正:下午讲题的时候whx大佬给出了正确的最差复杂度(O(NS)),因为权值大于(0),就算每个节点都是(1)它最多也只会加(S)次,所以不会爆掉。
    果然还是太菜了

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int n, s, x, y, cnt;
    int v[100005];
    int fa[100005];
    vector <int> p[100005];
    
    void dfs(int pl, int sum) {
    	sum += v[pl];
    	if (sum > s) return;
    	if (sum == s) {cnt++; return;}
    	for (int i = 0; i < p[pl].size(); i++) {
    		if (p[pl][i] != fa[pl])
    			dfs(p[pl][i], sum);
    	}
    }
    
    int main() {
    	scanf("%d %d", &n, &s);
    	for (int i = 1; i <= n; i++) scanf("%d", &v[i]);
    	for (int i = 1; i < n; i++) {
    		scanf("%d %d", &x, &y);
    		fa[y] = x; 
    		p[x].push_back(y);
    	}
    	for (int i = 1; i <= n; i++) dfs(i, 0);
    	printf("%d", cnt);
    	return 0;
    }
    

    总结:

    没有非正数+(S)的超小范围=暴力满分

  • 相关阅读:
    卷积神经网络要点解析
    quicksork解析
    梳理知识点(一)
    高斯混合模型以及EM算法
    adaboost/gdbt/xgboos/random forestt的异同点
    Anki使用
    Markdown写作入门
    VBox复制虚拟机镜像后的操作
    Hadoop集群之vsftpd设置
    使用Oracle函数将银行归类,方便引用
  • 原文地址:https://www.cnblogs.com/Sheffield/p/13452133.html
Copyright © 2020-2023  润新知