首页 > 其他分享 >树形dp

树形dp

时间:2023-04-06 15:45:33浏览次数:47  
标签:idx extra int add 树形 dp

思路

定义

  • 定义f[i][0]表示以i为根的子树尽量用到d[i]-1条边的最大可能(留一条边给父节点联通用)
  • f[i][1]表示以i为根的子树尽量用到d[i]条边的最大可能

转移

  • 就是那个最简单的树形dp,不能相邻放的
  • f[i][0] = f[j][1],f[j][0] + w[idx](j为前d[i]-1条最大的子路)
  • f[i][1] = f[i][0] + (接着最大的一条边)
#include<bits/stdc++.h>
#define debug1(a) cout<<#a<<'='<< a << endl;
#define debug2(a,b) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<endl;
#define debug3(a,b,c) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<endl;
#define debug4(a,b,c,d) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<endl;
#define debug5(a,b,c,d,e) cout<<#a<<" = "<<a<<"  "<<#b<<" = "<<b<<"  "<<#c<<" = "<<c<<"  "<<#d<<" = "<<d<<"  "<<#e<<" = "<<e<<endl;
#define debug0(x) cout << "debug0: " << x << endl
#define fr(t, i, n)for (long long i = t; i < n; i++)
#define YES cout<<"Yes"<<endl
#define nO cout<<"no"<<endl
#define fi first
#define se second
#define int long long
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;

//#pragma GCC optimize(3,"Ofast","inline")
//#pragma GCC optimize(2)

const int N = 3e5+10,M = N*2;
int h[N], e[M], ne[M], w[M], idx;
int d[N];
int f[N][2];
bool st[N];
void add(int a, int b,int c)  // 添加一条边a->b
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}

void solve() 
{
    for(int i=0; i<N; i++)h[i] = -1;

    int n;cin >> n;
    for(int i = 1;i <= n;i ++)cin >> d[i];
    for(int i = 0; i < n-1; i++)
    {
        int a,b,c;cin >> a >> b >> c;
        if(c < 0)continue;
        add(a,b,c);
        add(b,a,c);
    }

    function<void(int,int)> dfs = [&](int u,int p)
    {
        st[u] = 1;
        
        vector<int> extra;
        int inist = 0;
        for(int i = h[u];i != -1;i = ne[i])
        {
            int j = e[i];
            if(j == p)continue;
            dfs(j,u);
            inist += f[j][1];
            if(d[j] && f[j][0] + w[i] - f[j][1] > 0)extra.push_back(f[j][0] + w[i] - f[j][1]);
        }
        sort(extra.begin(),extra.end(),greater<int>());
        
        f[u][0] = f[u][1] = inist;
        for(int i = 0;i < min(d[u],(int)extra.size());i ++)
        {
            f[u][0] = f[u][1];
            f[u][1] += extra[i];
        }
        if(d[u] > (int)extra.size())f[u][0] = f[u][1];
        
    };

    int ans = 0;
    for(int i = 1;i <= n;i ++)
        if(!st[i]){
            
            dfs(i,-1);
            //debug3(i,f[i][1],f[i][0]);
            ans += max(f[i][0],f[i][1]);
        }

    cout << ans << endl;
}

signed main()
{
    /*
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    */
    int T = 1;//cin >> T;
	
    while(T--){
        solve();
    }
    return 0;
}
/*

*/

标签:idx,extra,int,add,树形,dp
From: https://www.cnblogs.com/cfddfc/p/17292951.html

相关文章

  • 设置Sweet Home 3D 支持高DPI显示
    SweetHome3D没有默认检测当前屏幕的DPI大小,而进行相应的缩放,需要添加下面的环境变量手动设置一下。JAVA_OPTS=-Dcom.eteks.sweethome3d.resolutionScale=1.5......
  • 给技术新人的ODPS优化建议
    数据开发基本都是从陌生到熟悉,但是写多了就会发现各种好用的工具/函数,也会发现各种坑,本文分享了作者从拿到数据到数据开发到数据监控的一些实操经验。写在前面本文档是组内的一份算法ODPS离线开发分享,仅列出了这些年积累下来的一些重要经验和结论,特别是在算法日常数据处理和调度中......
  • Javascript中扁平化数据结构与JSON树形结构转换详解
    Javascript中扁平化数据结构与JSON树形结构转换详解原文链接:https://www.jb51.net/article/247525.htm+目录一.先说简单的树形结构数扁平化处理二.再讲将扁平化数据结构转JSON树状形结构扩充一个知识点:forin与forof的区别:总结不废话,直接开干一.先说简单的树形结构数......
  • 【容斥、状压dp】主旋律 题解
    【清华集训2014】主旋律题解神秘题。题目简述给你一个有向图\(G=(V,E)\)。求有多少\(E\)的子集\(E'\)使得新图\(G'=(V,E')\)是强连通图。强连通图的定义是任意两点\(u,v\)均存在\(u\tov,v\tou\)的路径。\(n\leq15,m\leqn\times(n-1)\)。解题思路......
  • Docker yum install的时候报错:Rpmdb checksum is invalid: dCDPT(pkg checksums): ...
    闲话就不说了,直接上Dockerfile:FROMhub.c.163.com/library/centos:7.2.1511MAINTAINERbyzsk_johnRUNyum-yinstallvimnet-tools&&yumcleanallEXPOSE22CMD["/bin/bash","-D"]注意一点,如果拆开写RUN,也就是yuminstallvim-y&&yuminst......
  • DPST1091 23T1 CS Pizzeria求解
    CSPizzeriaPanteawantstostartapizzashop(pizzeria),butshehasnowaytomanageit.Howwilltheykeeptrackoftheirorders?Howwilltheykeeptrackoftheirfinances?DPST1091isrequestingyoutobuildaprogramwhichwillhelpthemmanagethei......
  • Disjoint-Set-Union Sum (诈骗题)(区间DP, 位置顺序!!!!)
    题目大意: 给出一个序列P,n个点每次可以选择2个相邻区间进行合并,会产生一个贡献值,当然合并n-1就合并完了,问在所有的情况下,贡献和是多少  思路:易错点:这个所有情况,你枚举的合并的那个先后顺序是有关系的!!!因此直接去区间dp只能把各个合并的情况给弄......
  • Leetcode(剑指offer专项训练)——DP专项(7)
    矩阵中的距离题目:给定一个由0和1组成的矩阵mat ,请输出一个大小相同的矩阵,其中每一个格子是mat中对应位置元素到最近的0的距离。两个相邻元素间的距离为1。链接TLS思路题解暴力DFS的结果是超时......
  • WordPress添加前端代码演示功能详解–无须插件
    如果用Wordpress来写技术博客,尤其是写关于前端部分的,我相信会有不少博主希望能在博客里添加演示功能。这样读者对文章所说的代码效果会有个直观的感受,也能知晓其效果是否为自己所需的。另外一方面,添加演示也意味着文中的代码是没有问题的,增加文章可读性与可信性。添加演示代码功能......
  • 状压DP
    [acwing]291.蒙德里安的梦想/* 横放的方案数就等于总方案数,因为横着放完后,再竖着放是唯一的 dp[i][j]表示第i列状态为j的方案数 状态为j是指:各行用0或1表示摆放状态 :若某行为0,表示竖放或由前一列伸出 :若某行为1,表示横放并向后一列伸出 ......