zoukankan      html  css  js  c++  java
  • $P3047 [USACO12FEB]$附近的牛$Nearby Cows$

    #$Description$ [题面](https://www.luogu.org/problem/P3047) 题意是给你一颗$n$个节点的树和$k(kleq 20)$,每条边权是$1$,告诉你$n$个点的点权,输出到点$i$距离$leq k$的所有点的点权和 #$Solution$ 感觉很不可做,一开始考虑维护距离为$k$的点,然后跟着当前点往一个方向走,发现根本没法实现。 考虑到一维状态不够用,肯定要使用二维$dp$,第一维已经达到了$1e5$的数据量,盲猜第二维是$leq k$的数。 于是$dp[i][j]$表示到$i$点距离$leq j$的点权和,考虑一个子节点是$s$,如何进行转移。 若要求子节点的所有贡献都能转移到$dp[i][j]$,一定要转移来的是距离不超过$j-1$的,因为从$i-->s$需要走一步,所以剩下走到最远只能走$j-1$步 所以$dp[i][j]+=dp[s][j-1](sin son[i])$ 这样做向下找保证两个边界恰好相同,但向上找就会发现$dp[s][j-1]$是$s$向上走$j-1$步,也就是走$1$步到$i$,再从$i$往其他方向走$j-2$步 看这张图 ![](https://img2018.cnblogs.com/blog/1564177/201911/1564177-20191103162624013-46334772.png) 红色部分是加入的$dp[s][j-1]$,我们需要消除红色部分超越父亲节点到其他节点的影响,所以每次$+dp[s][j-1]-dp[i][j-2]$即可 但最后注意到中间一部分(也就是$i$向外扩展$j-2$)每次都被减去,最后没有加入中间部分答案,所以只需要再加一次$dp[i][j-2]$即可 有点类似容斥的思想 具体实现因为每次都要减去$dp[i][j-2]$,所以统计完所有子树后$-dp[i][j-2]*(son[i]-1)$即可 但注意到一个问题,如果使用常规的$dfs$序父亲无法统计,于是根本不用$dfs$,直接$for$循环所有节点和所有距离统计答案就行,但要注意枚举顺序的问题,假如外层先枚举节点,那么$i=1,j=3$时其他节点的$j=2$的情况都没被更新,这样$dp$肯定错了,所以换一换枚举顺序,外层先枚举$j$也就是距离即可 #$Code$ ``` #include #include #include #include #define re register #define maxn 100100 using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct Edge{ int v,nxt; }e[maxn<<2]; int n,k,x,y,c[maxn],head[maxn],cnt; int dp[maxn][25],du[maxn]; inline void add(int u,int v) { e[++cnt].v=v; e[cnt].nxt=head[u]; head[u]=cnt; du[u]++; } void DP() { for(re int j=1;j<=k;++j) for(re int i=1;i<=n;++i) { for(re int p=head[i];p;p=e[p].nxt) dp[i][j]+=dp[e[p].v][j-1]; if(j==1) dp[i][j]+=dp[i][0]; else dp[i][j]-=dp[i][j-2]*(du[i]-1); } } int main() { n=read(),k=read(); for(re int i=1;i
  • 相关阅读:
    C#面向对象之封装。
    python 数据处理学习pandas之DataFrame
    有用的vscode快捷键大全+自定义快捷键
    angular中控制器之间传递参数的方式
    angular.module 详解
    如何让类数组也使用数组的方法比如:forEach()
    CSS之flex兼容
    JavaScript中捕获/阻止捕获、冒泡/阻止冒泡
    Vue2.0 探索之路——生命周期和钩子函数的一些理解
    React 生命周期
  • 原文地址:https://www.cnblogs.com/Liuz8848/p/11787629.html
Copyright © 2011-2022 走看看