题目大意:给定一棵有根树,每个节点有权值,求有多少链上的权值和为S,要求链上节点的深度必须单调(即这条链由某个节点出发指向根)
DFS一遍,当深搜到一个点时将这个点加入队列,同时队头向后调整,使队列中元素之和<=s,记录ans
当一个点出栈时将队尾删除,同时队头向前调整,使队列中元素之和刚好<=s
这题1s略卡时间。。。不过我旁边的哥们用nlogn的算法超时700ms过去的0.0 这怎么过去的0.0 误差也太大了吧0.0
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 100100 using namespace std; struct abcd{ int to,next; }table[M<<1]; int head[M],tot; int n,s,ans,sum,a[M],fa[M],q[M],r,h; void Add(int x,int y) { table[++tot].to=y; table[tot].next=head[x]; head[x]=tot; } void DFS(int x) { int i; q[++r]=a[x]; sum+=a[x]; while(sum>s) sum-=q[++h]; if(sum==s) ++ans; for(i=head[x];i;i=table[i].next) { if(table[i].to==fa[x]) continue; fa[table[i].to]=x; DFS(table[i].to); } sum-=q[r--]; while(h&&sum+q[h]<=s) sum+=q[h--]; } int main() { int i,x,y; cin>>n>>s; for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<n;i++) scanf("%d%d",&x,&y),Add(x,y),Add(y,x); DFS(1); cout<<ans<<endl; }
原文地址:http://blog.csdn.net/popoqqq/article/details/40106495