【Luogu】P3155叶子的染色(树形DP)

  题目链接

  树形DP水题qwq。

  设f[i][j]是以i为根的子树,染成j色,且满足内部需求的最少染色节点数。

  设to是x的子节点,那么状态转移方程如此设计:

  1、f[i][0]

  这个状态表示i不染色,那显然很好办,对于每个to从f[to][1],f[to][2]和f[to][0]里选一个最小的即可。

  转移方程$f[x][0]=\sum\limits_{to}min(f[to][1],f[to][2],f[to][0])$

  2、f[i][1]

  此时i染成黑色。那么对于每个to我们发现,既可以让它继续染白,也可以把本来染成黑色的to改为无色,让染成黑色的i来发挥to的作用。

  于是$f[x][1]=\sum\limits_{to}min(f[to][1]-1,f[to][2])$

  f[i][2]类似,不再赘述。

  

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cstring>
#define maxn 50020
using namespace std;

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch==‘-‘)    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-‘0‘;
        ch=getchar();
    }
    return num*f;
}

int f[maxn][3];
int q[maxn];

struct Edge{
    int next,to;
}edge[maxn*2];
int head[maxn],num;
inline void add(int from,int to){
    edge[++num]=(Edge){head[from],to};
    head[from]=num;
}

int root;
int m,n;
void dfs(int x,int fa){
    if(x<=n){
        f[x][q[x]+1]=1;
        f[x][(q[x]^1)+1]=f[x][0]=1000000;
        return;
    }
    int whi=0,bla=0;
    for(int i=head[x];i;i=edge[i].next){
        int to=edge[i].to;
        if(to==fa)    continue;
        dfs(to,x);
        f[x][0]+=min(f[to][1],min(f[to][2],f[to][0]));
        whi+=min(f[to][2]-1,f[to][1]);
        bla+=min(f[to][1]-1,f[to][2]);
    }
    f[x][2]=whi+1;
    f[x][1]=bla+1;
    return;
}

int main(){
    m=read(),n=read();
    for(int i=1;i<=n;++i)    q[i]=read();
    for(int i=1;i<m;++i){
        int from=read(),to=read();
        add(from,to);
        add(to,from);
    }
    root=n+1;
    dfs(root,root);
    printf("%d",min(f[root][0],min(f[root][1],f[root][2])));
    return 0;
}

/*
10 5
1 0 1 1 0
1 6
6 2
6 3
7 6
7 4
7 10
10 9
9 8
8 5
*/

原文地址:https://www.cnblogs.com/cellular-automaton/p/8319796.html

时间: 2024-10-01 04:51:34

【Luogu】P3155叶子的染色(树形DP)的相关文章

【bzoj1304】[CQOI2009]叶子的染色 树形dp

题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一个有色结点(哪怕是这个叶子本身). 对于每个叶结点u,定义c[u]为从根结点从U的简单路径上最后一个有色结点的颜色.给出每个c[u]的值,设计着色方案,使得着色结点的个数尽量少. 输入 第一行包含两个正整数m, n,其中n是叶子的个数,m是结点总数.结点编号为1,2,…,m,其中编号1,2,… ,n是叶子.以下

[CQOI2009] 叶子的染色 - 树形dp

给一棵 \(m\) 个结点的无根树,你可以选择一个度数大于 \(1\) 的结点作为根,然后给一些结点着以黑色或白色.方案应保证根结点到每个叶子的简单路径上都至少包含一个有色结点. 对于每个叶结点 \(u\) ,定义 \(c[u]\) 为从根结点从 \(u\) 的简单路径上最后一个有色结点的颜色.给出每个 \(c[u]\) 的值,设计着色方案,使得着色结点的个数尽量少. Solution 选择任意一个点为根,答案都是相同的 随便选一个点为根,然后设 \(f[i][0/1]\) 表示将 \(i\)

【BZOJ4033】[HAOI2015]树上染色 树形DP

[BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益.问收益最大值是多少. Input 第一行两个整数N,K. 接下来N-1行每行三个正整数fr,to,dis,表示该树中存在一条长度为dis的边(fr,to). 输入保证所有点之间是联通的. N<=2000,0<=K&l

Luogu P1122 最大子树和 树形DP

题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明就向老师提出了这个问题: 一株奇怪的花卉,上面共连有N 朵花,共有N-1条枝干将花儿连在一起,并且未修剪时每朵花都不是孤立的.每朵花都有一个"美丽指数",该数越大说明这朵花越漂亮,也有"美丽指数"为负数的,说明这朵花看着都让人恶心.所谓"修剪",意为

bzoj4033: [HAOI2015]树上染色(树形dp)

4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3269  Solved: 1413[Submit][Status][Discuss] Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的N-K个点染成白色.将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益. 问收益最大值是多少. Input 第一

[luogu3155 CQOI2009] 叶子的染色(树形dp)

传送门 Solution 十分简单的树形dpQwQ,转移关系:父亲染了儿子不用染 只需要确定根就是简单树形dp,而其实根可以随便取一个非叶子节点 可以分情况讨论发现答案并不会改变 Code //By Menteur_Hxy #include <cmath> #include <vector> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream&

P3155 [CQOI2009]叶子的染色

P3155 [CQOI2009]叶子的染色 题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一个有色结点(哪怕是这个叶子本身). 对于每个叶结点u,定义c[u]为从根结点从U的简单路径上最后一个有色结点的颜色.给出每个c[u]的值,设计着色方案,使得着色结点的个数尽量少. 输入输出格式 输入格式: 第一行包含两个正整数m, n,其中n是叶子的个数,m是结点总数

luogu 3155 [CQOI2009]叶子的染色

题目描述 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一个有色结点(哪怕是这个叶子本身). 对于每个叶结点u,定义c[u]为从根结点从U的简单路径上最后一个有色结点的颜色.给出每个c[u]的值,设计着色方案,使得着色结点的个数尽量少. 输入格式 第一行包含两个正整数m, n,其中n是叶子的个数,m是结点总数.结点编号为1,2,...,m,其中编号1,2,... ,n

UVA1218 Perfect Service(染色问题--树形DP)(好题,通法)

题意:一棵树,进行染色,每个没染色的节点恰好和一个染色的节点相连,求染色的节点最少的个数X(以下均以X代表子问题的解) 思路:树形DP,细化状态,从而对每个节点的每种状态互相递推 这里如何细化状态是难点,而且也是这类难题的共同问题 很容易知道每个节点i至少两个状态:dp[i][0]: i没染上色时以i的子树的X.dp[i][1]: i被染色以i为子树的X 但是仅仅这两个状态无法实现状态转移因为: dp[u][0]=sum(dp[v][0],dp[v][1])+1  (dp[u][0]可以找到状态