P3252 [JLOI2012]树
题目描述
在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。
输入输出格式
输入格式:
第一行是两个整数N和S,其中N是树的节点数。 第二行是N个正整数,第i个整数表示节点i的正整数。 接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
输出格式:
输出路径节点总和为S的路径数量。
输入输出样例
输入样例#1:
3 31 2 31 21 3
输出样例#1:
2
说明
对于100%数据,N<=100000,所有权值以及S都不超过1000。
zz,才开时的时候读错题目了,然后数组内存的与我要存的不一样,结果我竟然忘记改了!!傻不拉几的交了6遍,发现全部零分、、、
for循环,dfs找一每一个点往下的路径,超时
#include#include #include #include #define N 210000using namespace std;bool vis[N];int n,m,x,y,ans,tot,root;int a[N],fa[N],sum[N],deep[N],head[N];int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='0')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}struct Edge { int to,next,from;}edge[N<<1];int add(int x,int y){ tot++; edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot;}int dfs(int x){ sum[x]=sum[fa[x]]+a[x]; for(int i=head[x];i;i=edge[i].next) { int to=edge[i].to; if(!vis[to]&&fa[x]!=to) { vis[to]=true; dfs(to); vis[to]=false; } }}int main(){ n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i
依旧是dfs,不过我们不是以每一个点为根节点进行搜索,而是在dfs到每一个点的时候,我们以每一个点为叶子节点,然后向上搜索,判断路径长度是否已经到达m,我们要在向上搜的时候搜到根节点便停止搜索,防止在while中死循环!
#include#include #include #include #define N 210000using namespace std;bool vis[N];int n,m,x,y,ans,tot,sum,root;int a[N],fa[N],deep[N],head[N];int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='0')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f;}struct Edge { int to,next,from;}edge[N<<1];int add(int x,int y){ tot++; edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot;}int pd(int x){ sum=a[x]; while(sum