zoukankan      html  css  js  c++  java
  • luogu P3254 树 解题报告

    题目描述

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

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

    输出格式

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

    输入输出样例

    输入:
    3 3
    1 2 3
    1 2
    1 3
    输出:
    2

    说明/提示

    对于100%数据,N<=100000,所有权值以及S都不超过1000。

    题解

    这是个dd题!
    要多dd就有多dd!
    n方直接过不需要动脑子
    关键点:
    1.处理根节点
    2.当前值大于s时break

    代码

    #include <iostream>
    #include <cstdio>
    #define ll long long
    #define R register
    using namespace std;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while (c>'9'||c<'0') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return x*f;
    }
    const int maxn=1e5+5;		
    int s,n,ans;
    int a[maxn],fa[maxn];
    
    void init(){
    	n=read(),s=read();
    	for (R int i(1);i<=n;++i) a[i]=read(),fa[i]=i;
    	for (R int i(1),x,y;i<n;++i) x=read(),y=read(),fa[y]=x;
    }
    inline int getroot(int u){
    	if (fa[u]==u) return u;
    	return getroot(fa[u]);
    }
    void doit(){
    	int rt=getroot(1);
    	for (R int i(1);i<=n;++i){
    		int sum=a[i];
    		if (sum==s) ans++;
    		if (sum>s) continue;
    		int j=i;
    		while (j!=rt){
    			j=fa[j];
    			sum+=a[j];
    			if (sum==s) ++ans;
    			if (sum>s) break;
    		}
    	}
    	printf("%d
    ",ans);
    }
    int main(){
    	init();
    	doit();
    	return 0;
    }
    
  • 相关阅读:
    Linux:删除程序
    Linux:目录操作
    Linux:加载硬盘
    mysql:查询结果添加序列号
    mysql:结果集去重
    mysql:字符串转换为日期类型
    MVC:上传文件时限制文件类型
    WebApi:WebApi的Self Host模式
    WebApi:过滤器的种类
    几种知名开源富文本编辑器记录和对比(仅供参考)
  • 原文地址:https://www.cnblogs.com/cancers/p/11316189.html
Copyright © 2011-2022 走看看