随笔 - 58,  文章 - 0,  评论 - 4,  阅读 - 3296

 一、题目描述:

  给你一棵 n 个点的树,点带权,对于每个节点,求出距离它不超过 k 的所有节点权值和。n<=1e5,k<=20。


 二、解题思路:

  这题一开始想了一个 O(knlogn) 的线段树合并,写了一半感觉不好转移,最后写了十几分钟的 dp 写出来了。( dp代码就是短 )

  两遍 dfs 。第一遍统计从儿子到父亲,第二遍统计从父亲到儿子,注意一些细节即可,不多讲。时间复杂度 O(kn)。


  、完整代码:

复制代码
 1 #include<iostream>
 2 #include<cstring>
 3 #define N 100010
 4 using namespace std;
 5 int n,k,u1,v1;
 6 int c[N],ans[N],f[N][25];
 7 struct EDGE{
 8     int v,nxt;
 9 }edge[N*2];
10 int head[N],cnt;
11 void add(int u,int v)
12 {
13     edge[++cnt].v=v;
14     edge[cnt].nxt=head[u];
15     head[u]=cnt;
16 }
17 void dfs1(int now,int ff)
18 {
19     f[now][0]+=c[now];
20     for(int i=head[now];i!=-1;i=edge[i].nxt)
21         if(edge[i].v!=ff)
22         {
23             dfs1(edge[i].v,now);
24             for(int j=1;j<=k;j++)
25                 f[now][j]+=f[edge[i].v][j-1];
26         }
27 }
28 void dfs2(int now,int ff)
29 {
30     for(int i=head[now];i!=-1;i=edge[i].nxt)
31         if(edge[i].v!=ff)
32         {
33             for(int j=k;j>=2;j--)
34                 f[edge[i].v][j]-=f[edge[i].v][j-2];
35             //这里注意倒序枚举 
36             for(int j=2;j<=k;j++)
37                 f[edge[i].v][j]+=f[now][j-1];
38             f[edge[i].v][1]+=c[now];
39             dfs2(edge[i].v,now);
40         }
41 }
42 int main()
43 {
44     ios::sync_with_stdio(false);
45     cin.tie(0);cout.tie(0);
46     cin>>n>>k;
47     memset(head,-1,sizeof(head));
48     for(int i=1;i<n;i++)
49     {
50         cin>>u1>>v1;
51         add(u1,v1),add(v1,u1);
52     }
53     for(int i=1;i<=n;i++)
54         cin>>c[i];
55     dfs1(1,0);dfs2(1,0);
56     for(int i=1;i<=n;i++)
57         for(int j=0;j<=k;j++)
58             ans[i]+=f[i][j];
59     for(int i=1;i<=n;i++)
60         cout<<ans[i]<<'\n';
61     return 0;
62 }
复制代码

四、做题心得:

  感觉这题真没啥难度,不过做了一道蓝题还是挺高兴的啦。拜拜!

posted on   trh0630  阅读(66)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示