[USACO12FEB]Nearby Cows G (换根dp+容斥)

在这里插入图片描述

思路:这题涉及距离k,k肯定要作为一个状态的。首先选一个根节点,dfs序作为有根树。

我们设d[i][j] : 顶点i向下dfs, j距离内的点权和,可以直接dfs求得,dp[i][0]为边界

递推过程:d[i][j]=c[i]+Σd[child][j-1]

设f[i][j] : 距离顶点i ,j距离内的点权和, f[i][0] f[1][j]作为边界. 可以直接求出来

递推过程是父节点->子节点 , f[child][j]=f[rt][j-1]+d[child][j]-w;
其中,当j>=2 w=d[child][j-2] 否则w=0;

这里为啥要减去d[child][j-2]呢?因为当j>=2,f[rt][j-1]会包括进d[child][j-2]的这些点,相当于重复计数了,所以根据容斥原理得减掉。

最终答案就是f[i][k]

总的来说,这题比较巧妙,首先是预处理d[i][k] 。

然后是想到f[[i][j]中的边界是根节点,从而确立父节点->孩子节点的方向。

最后是对于换根过程中产生的重复计算部分的处理,减去d[child][j-2]

//#pragma comment(linker, "/STACK:102400000,102400000")//手动扩栈
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<math.h>
#include<set>
#include<unordered_map>
using namespace std;
#define LL long long
#define ULL unsigned long long
const int INF=0x3f3f3f3f;
const double eps=1e-5;
const int maxn=1e5+7;
//思路:d[i][j]表示点i向下dfs,距离小于等于j的点的个数,包括自己  f[i][j] 离点i j距离以内的点的个数 
//f[i][j]=f[father[i]][j-1]+d[i][j]-
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值