zoukankan      html  css  js  c++  java
  • 题解 P3252 【[JLOI2012]树】

    (Huge{[JLOI2012]树})

    题目描述

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:

    3 3
    1 2 3
    1 2
    1 3

    输出样例#1:

    2

    说明

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

    思路

    安利博客

    题目传送门


    先让我们看这句话

    路径中节点的深度必须是升序的。

    那就要保证是向下搜的呗。

    用链式前向星存边,记录父亲, 只要保证下个节点不是他的父亲即可

    读入时

    for(int i=1;i<=n-1;i++)
    	{
    		cin>>x>>y;
    		add(x,y);
    		fa[y]=x;
    	}
    

    搜索时

    if(fa[x]!=nxt)
    

    再看这句话

    路径不必一定从根节点开始。

    那就把点全枚举一边就行啊,

    for(int i=1;i<=n;i++)
    	{
    	    dfs(i,w[i]);	
    	}
    

    问有多少条路径的节点总和达到S

    当时本人不太明白的,是要到s才行,不能超过s。所以可以加入剪枝

    超过s就不用搜了qwq。
    达到s后ans++,不用搜了

    if(dis>s)
    	    return;
    	if(dis==s)
    	{
    		ans++;
    		return;
    	}
    

    下面献上简陋的代码

    不要抄袭,代码有锅QAQ

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define ll long long
    #define IL inline
    #define R register
    using namespace std;
    struct node{
    	int u,v;
    }fuck[100007];
    int head[100007],fa[100007],x,y,w[100007],n,s,tot=0,ans=0;
    IL void read(int &x)
    {
    	int f=1;x=0;char s=getchar();
    	while (s<'0'||s>'9'){if(s=='-') f=-1 s=getchar();}
    	while (s>='0'&&s<='9'){ x=x*10+s-'0'; s=getchar();}
    	x*=f; 
    }
    void add(int x,int y)
    {
    	fuck[++tot].u=head[x];//++?
    	fuck[tot].v=y;
    	head[x]=tot;
    }
    
    IL void dfs(int x,int dis)
    {
    	if(dis>s)
    	    return;
    	if(dis==s)
    	{
    		ans++;
    		return;
    	}
    	for(int i=head[x];i;i=fuck[i].u)
    	{
    		int nxt=fuck[i].v;
    		if(fa[x]!=nxt)
    		    dfs(nxt,dis+w[nxt]);
    	}
    }
    
    int main()
    {
        read(n);read(s);
        for(int i=1;i<=n;i++)
        	cin>>w[i];
    	for(int i=1;i<=n-1;i++)
    	{
    		cin>>x>>y;
    		add(x,y);
    		fa[y]=x;
    	}
    	for(int i=1;i<=n;i++)
    	{
    	    dfs(i,w[i]);	
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
    

    ({color{Gold}{By}})

    ({color{Gold}{enceladsu}})

  • 相关阅读:
    二分法查找
    全排列 递归实现 c 语言实现
    南阳oj 题目290 动物统计加强版 字典树
    蛇形填数
    南阳理工oj 题目289 苹果 01背包
    南阳理工 oj 题目38 布线问题
    南阳理工oj 题目85 有趣的数 Cantor数表
    CSU-1110 RMQ with Shifts (单点更新+区间最小值 zkw线段树)
    POJ-2387 Til the Cows Come Home
    HDU-2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/enceladus-return0/p/9583086.html
Copyright © 2011-2022 走看看