1. 程式人生 > >【[USACO12FEB]附近的牛Nearby Cows】

【[USACO12FEB]附近的牛Nearby Cows】

我記得我調這道題時中耳炎,發燒,於是在學長的指導下過了也沒有發題解

發現我自己的思路蠻鬼畜的

常規操作:\(f[i][j]\) 表示到\(i\)的距離為\(j\)的奶牛有多少隻,但注意這只是在第二遍dfs之後

在我的第一遍dfs中(就是下面那個叫build的函式),\(f[i][j]\)的含義是在i這課子樹中到\(i\)的距離為\(j\)的奶牛有多少隻,所以在第一遍dfs的時候,\(f[i][j]\)的狀態只會來自它的兒子們

於是在第一遍dfs就有一個異常簡單的方程

\[f[i][j]=\sum_{}f[k][j-1]\]

其中\(k\)\(i\)的兒子

如果我們欽定以1為根建樹的話,那麼1的子樹就是整棵樹,於是這個時候的\(f[1]\)

就是全樹意義下的答案了

而這個時候第二遍dfs就要登場了,第二遍dfs的意義就是利用父親去更新兒子,於是我們就又有一個簡單的方程了

\[f[k][j]=\sum_{}f[i][j-1]\]

其中\(k\)\(i\)的兒子

這樣的話肯定會有重複的,因為到\(i\)的距離為2的點包含到\(k\)距離為1的k的兒子們,而這些點位於\(k\)的子樹中的點已經在第一遍dfs的時候被加上了,於是我們在這裡簡單容斥就好了

於是就是程式碼了

#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define maxn 100001
using namespace std;
struct node
{
    int v,nxt;
}e[maxn<<1];
int f[maxn][21],s[maxn],head[maxn],deep[maxn];
int n,num,k;
inline int read()
{
    char c=getchar();
    int x=0;
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9')
      x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x;
}
inline void add(int x,int y)
{
    e[++num].v=y;
    e[num].nxt=head[x];
    head[x]=num;
}
inline void build(int r)
{
    for(re int i=head[r];i;i=e[i].nxt)
    if(!deep[e[i].v])
    {
        deep[e[i].v]=deep[r]+1;
        build(e[i].v);
        for(re int j=1;j<=k;j++)
        f[r][j]+=f[e[i].v][j-1];
    }
}
inline void dfs(int r)
{
    for(re int i=head[r];i;i=e[i].nxt)
    if(deep[e[i].v]>deep[r])
    {
        for(re int j=k;j>=2;j--)
            f[e[i].v][j]-=f[e[i].v][j-2];//簡單的容斥原理了
          //這裡的迴圈一定要倒序
        for(re int j=1;j<=k;j++)
            f[e[i].v][j]+=f[r][j-1];
        dfs(e[i].v);
    }
}
int main()
{
    n=read();
    k=read();
    int x,y;
    for(re int i=1;i<n;i++)
    {
        x=read();
        y=read();
        add(x,y);
        add(y,x);
    }
    for(re int i=1;i<=n;i++)
        s[i]=read(),f[i][0]=s[i];
    deep[1]=1;
    build(1);
    dfs(1);
    for(re int j=1;j<=n;j++)
    {
        int ans=0;
        for(re int i=0;i<=k;i++)
        ans+=f[j][i];
        printf("%d\n",ans);
    }
}