BZOJ 2783 JLOI2012 树 DFS

来源:互联网 发布:win10怎么安装mysql 编辑:程序博客网 时间:2024/04/30 09:27

题目大意:给定一棵有根树,每个节点有权值,求有多少链上的权值和为S,要求链上节点的深度必须单调(即这条链由某个节点出发指向根)

DFS一遍,当深搜到一个点时将这个点加入队列,同时队头向后调整,使队列中元素之和<=s,记录ans

当一个点出栈时将队尾删除,同时队头向前调整,使队列中元素之和刚好<=s

这题1s略卡时间。。。不过我旁边的哥们用nlogn的算法超时700ms过去的0.0 这怎么过去的0.0 误差也太大了吧0.0

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 100100using 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;}


0 0
原创粉丝点击