ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1223E Paint the Tree(树形DP)

2020-05-02 12:54:20  阅读:296  来源: 互联网

标签:ll Tree 着色 Paint edge 顶点 CF1223E 节点 dp


给出了一个由n个顶点组成的加权树。回想一下,树是一个没有圈的连通图。顶点ui和vi通过带权重wi的边连接。

 

让我们将树的k-着色定义为每个顶点的k-着色,这样每个颜色的使用次数就不会超过两次。你可以假设你有无限多的颜色可用。我们说,如果一条边的端点共享至少一种颜色(即存在一种指定给两个端点的颜色),那么它在给定的k-着色中是饱和的。

 

我们还将k-着色的值定义为饱和边的权重之和。

 

请计算给定树的k-着色的最大可能值。

 

你必须回答与q无关的问题。

 

第一行包含一个整数q(1≤q≤5⋅105)-查询数。

 

每个查询的第一行包含两个整数n和k(1≤n,k≤5⋅105)-树中的顶点数和分配给每个顶点的颜色数。

 

/*
 * cf1223E
 * 题意:
 * 给出一棵树,选择若干条边使边权值和最大,要求每个节点至多被k条边覆盖
 * 题解:
 * 树形dp。
 * 考虑子节点和父节点的关系可知有两种情况:
 * (1)子节点已经连完k条边则不可以与父节点连边。
 * (2)子节点留一条边和父节点连边。
 * 可以用dp[0][u]表示选择k条当前节点与子节点的边得到的以u为节点的子树的最大值
 * dp[1][u]表示选择k-1条当前节点与子节点的边得到的以u为节点的子树的最大值,与子树相连的边可以用优先队列维护
 */
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+2;
struct node {
    int u,v,next;
    ll w;
}edge[maxn<<1];
int head[maxn],tot;
int N,K;
ll dp[2][maxn],ans;
void addedge (int u,int v,ll w) {
    edge[tot].u=u;
    edge[tot].v=v;
    edge[tot].w=w;
    edge[tot].next=head[u];
    head[u]=tot++;
}
inline void dfs (int u,int pre) {
    priority_queue<ll> q;
    ll x=0;
    for (int i=head[u];i!=-1;i=edge[i].next) {
        int v=edge[i].v;
        if (v==pre) continue;
        dfs(v,u);
        x+=dp[0][v];
        if (dp[1][v]+edge[i].w-dp[0][v]>0)
            q.push({dp[1][v]+edge[i].w-dp[0][v]});
    }
    ll w=1;
    while (!q.empty()&&w<K) {
        ll t=q.top();
        q.pop();
        x+=t;
        w++;
    }
    dp[0][u]=dp[1][u]=x;
    if (!q.empty()) dp[0][u]+=q.top();
    ans=max(ans,max(dp[1][u],dp[0][u]));
}
int main () {
    int Q;
    scanf("%d",&Q);
    while (Q--) {
        ans=0;
        tot=0;

        scanf("%d%d",&N,&K);
        for (int i=0;i<=N;i++) {
            dp[1][i]=0;
            dp[0][i]=0;
            head[i]=-1;
        }
        for (int i=1;i<N;i++) {
            int u,v;ll w;
            scanf("%d%d%lld",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
        }
        dfs(1,0);
        printf("%lld\n",ans);
    }
}

 

接下来的n-1行中的每一行描述树的一个边。边i由三个整数ui、vi和wi(1≤ui,vi≤n,ui≠vi,1≤wi≤105)表示-它连接的顶点的标签和边的权重。可以保证给定的边形成一棵树。

 

保证所有查询的n和不超过5⋅105。

 

对于每个查询,打印一个整数-给定树的k-着色的最大值。

标签:ll,Tree,着色,Paint,edge,顶点,CF1223E,节点,dp
来源: https://www.cnblogs.com/zhanglichen/p/12817722.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有