P3252 [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。
zz,才开时的时候读错题目了,然后数组内存的与我要存的不一样,结果我竟然忘记改了!!傻不拉几的交了6遍,发现全部零分、、、
for循环,dfs找一每一个点往下的路径,超时
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 210000 using 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() { ,f=; char ch=getchar(); ; ch=getchar();} +ch-'; ch=getchar();} return x*f; } struct Edge { int to,next,from; }edge[N<<]; 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(); ;i<=n;i++) a[i]=read(); ;i<n;i++) { x=read(),y=read(); add(x,y);fa[y]=x; } ;i<=n;i++) { memset(sum,,sizeof(sum)); dfs(i); ;i<=n;i++) if(sum[i]==m) ans++; } printf("%d",ans); ; }
TLE的dfs
依旧是dfs,不过我们不是以每一个点为根节点进行搜索,而是在dfs到每一个点的时候,我们以每一个点为叶子节点,然后向上搜索,判断路径长度是否已经到达m,我们要在向上搜的时候搜到根节点便停止搜索,防止在while中死循环!
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 210000 using 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() { ,f=; char ch=getchar(); ; ch=getchar();} +ch-'; ch=getchar();} return x*f; } struct Edge { int to,next,from; }edge[N<<]; 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<m) { sum+=a[fa[x]],x=fa[x]; if(!fa[x]) break; } if(sum==m) return true; return false; } int dfs(int 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; if(pd(to)) ans++; pd(to),dfs(to); vis[to]=false; } } return ans; } int main() { n=read(),m=read(); ;i<=n;i++) a[i]=read(); ;i<n;i++) { x=read(),y=read(); add(x,y);fa[y]=x; } ;i<=n;i++) if(!fa[i]) root=i; dfs(root); printf("%d",ans); ; }