[CQOI2009]叶子的染色

https://www.zybuluo.com/ysner/note/1307594

题面

戳我

解析

一开始脑抽了,状态转移时默认直接在子结点染色。。。

其实这道题还是很简单的。

设\(dp[0/1/2][u]\)表示子树内的叶子结点还需要颜色\(0/1\),或都不需要颜色。

然后直接转移就对了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=1e4+100;
int n,m,h[N],cnt,w[N],dp[3][N];
struct Edge{int to,nxt;}e[N<<1];
il void add(re int u,re int v){e[++cnt]=(Edge){v,h[u]};h[u]=cnt;}
il ll gi()
{
  re ll x=0,t=1;
  re char ch=getchar();
  while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar();
  if(ch==‘-‘) t=-1,ch=getchar();
  while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-48,ch=getchar();
  return x*t;
}
il void dfs(re int u,re int fa)
{
  if(u<=m) dp[2][u]=1,dp[!w[u]][u]=1e5;
  for(re int i=h[u];i+1;i=e[i].nxt)
    {
      re int v=e[i].to;
      if(v==fa) continue;
      dfs(v,u);
      dp[0][u]+=min(dp[0][v],dp[2][v]);
      dp[1][u]+=min(dp[1][v],dp[2][v]);
      dp[2][u]+=dp[2][v];
    }
  dp[2][u]=min(dp[2][u],min(dp[1][u],dp[0][u])+1);
}
int main()
{
  memset(h,-1,sizeof(h));
  n=gi();m=gi();
  fp(i,1,m) w[i]=gi();
  fp(i,1,n-1)
    {
      re int u=gi(),v=gi();
      add(u,v);add(v,u);
    }
  dfs(n,0);
  printf("%d\n",dp[2][n]);
  return 0;
}                                      

原文地址:https://www.cnblogs.com/yanshannan/p/9775674.html

时间: 2024-07-30 07:37:42

[CQOI2009]叶子的染色的相关文章

BZOJ 1304: [CQOI2009]叶子的染色

1304: [CQOI2009]叶子的染色 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 566  Solved: 358[Submit][Status][Discuss] Description 给一棵m个结点的无根树,你可以选择一个度数大于1的结点作为根,然后给一些结点(根.内部结点和叶子均可)着以黑色或白色.你的着色方案应该保证根结点到每个叶子的简单路径上都至少包含一个有色结点(哪怕是这个叶子本身). 对于每个叶结点u,定义c[u]为从根结

1304: [CQOI2009]叶子的染色 - BZOJ

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

P3155 [CQOI2009]叶子的染色

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

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

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

bzoj千题计划233:bzoj 1304: [CQOI2009]叶子的染色

http://www.lydsy.com/JudgeOnline/problem.php?id=1304 结论1:根节点一定染色 如果根节点没有染色,选择其子节点的一个颜色,那么所有这个颜色的子节点都不用染色.答案不会更差. 结论2:相邻节点不会染同一种颜色 将深度更大的那个有色节点变成无色仍然满足要求 结论3:任意一个非叶子节点做根,对答案都没有影响. 考虑将原根节点的一个自己点换成根,原来到根最近的颜色节点不变 所以,任取一个非叶子节点做根 dp[x][0/1]表示x染黑/白,使其子树内叶子

luogu 3155 [CQOI2009]叶子的染色

题目描述 给一棵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\)

bzoj1304: [CQOI2009]叶子的染色

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

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

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