cogs2478 简单的最近公共祖先 树形dp

填坑……链接:http://cogs.pro/cogs/problem/problem.php?pid=2478

题意:求出:

日常题面不符系列……实际上这是个树归……从下向上,对于每个节点,他对于某个点做出的贡献就是子树的大小乘上(子树总大小减去这棵子树大小)再加上该点乘权值,用式子写就是$ans[root]=size[root]*(sum((size[root]-size[belong[v]]))+1)$。

递推即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=1000005;
 7 struct node
 8 {
 9     int from,to,next;
10 }edge[maxn<<1];
11 int head[maxn],tot;
12 void addedge(int u,int v)
13 {
14     edge[++tot]=(node){u,v,head[u]};head[u]=tot;
15 }
16 int weight[maxn],n,size[maxn];
17 long long ans=0;
18 void dfs(int root)
19 {
20     size[root]=1;
21     for(int i=head[root];i;i=edge[i].next)
22     {
23         int v=edge[i].to;
24         if(size[v])continue;
25         dfs(v);
26         ans+=1ll*size[v]*1ll*weight[root]*1ll*size[root];
27         size[root]+=size[v];
28     }
29     ans+=1ll*weight[root];
30 }
31 int haha()
32 {
33     freopen("easy_LCA.in","r",stdin);
34     freopen("easy_LCA.out","w",stdout);
35     scanf("%d",&n);
36     for(int i=1;i<=n;i++)scanf("%d",&weight[i]);
37     for(int i=1;i<n;i++)
38     {
39         int x,y;scanf("%d%d",&x,&y);
40         addedge(x,y);addedge(y,x);
41     }
42     dfs(1);
43     printf("%lld\n",ans);
44 }
45 int sb=haha();
46 int main(){;}
cogs2478

 

转载于:https://www.cnblogs.com/Loser-of-Life/p/7357197.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值