题目大意:给定一棵有根树,每个节点有权值,求有多少链上的权值和为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;
}