树的中心和重心&树上背包

树的中心和重心

求树的中心:

法1:F[i]为以i为起点的最长链长度

枚举深度最小的点,全部枚举

void dfs(int fa,int x){
    for(int i = head[x];i;i = nxt[i]){
        if(to[i]==fa) continue;
        dfs(x,to[i]);
        ans = max(ans,f[x]+f[to[i]]+1); //是否形成更长链 
        f[x] = max(f[x],f[to[i]]+1); //尝试合并 
    }
    return;
}

法2:两次dfs,

第一次:以任意点i为起点,寻找离i最远点j

第二次:以j为起点,寻找最远点k

答案:j-k

树上背包

有体积为v价值为w的背包构成树,选了一个节点就要选父亲,问不超过体积V价值最大的算法

解:每个子树就是一个泛化物品。

f[u][i]表示以u为根体积为i的最大价值

 

void dfs(int fa,int x){
    for(int i = w[x];i <= m;i++) f[x][i] = v[x];
    for(int i = head[x];i;i = nxt[i]){
        if(to[i] == fa) continue;
        dfs(x,to[i]);
        for(int j = m;j;j--){ //枚举体积
            for(int k = 0;k <= j-w[x];k++){
                f[x][j] = max(f[x][j],f[x][j-k]+f[to[i]][k]);
            }
        }
        
    }
}

 

posted @ 2022-02-12 15:46  yinfelix  阅读(78)  评论(0)    收藏  举报