前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10161. 「一本通 5.2 练习 4」叶子的染色

10161. 「一本通 5.2 练习 4」叶子的染色

作者头像
yzxoi
发布2022-09-19 12:16:35
2160
发布2022-09-19 12:16:35
举报
文章被收录于专栏:OI

10161. 「一本通 5.2 练习 4」叶子的染色

题意

给一棵有 m 个节点的无根树,你可以选择一个度数大于 1 的节点作为根,然后给一些节点(根、内部节点、叶子均可)着以黑色或白色。你的着色方案应保证根节点到各叶子节点的简单路径上都包含一个有色节点,哪怕是叶子本身。对于每个叶子节点 u,定义 c_u 为从根节点到 u 的简单路径上最后一个有色节点的颜色。给出每个 c_u 的值,设计着色方案使得着色节点的个数尽量少。

思路

为根节点的子树最少的着色个数 。 那么很容易就可以知道:

f[x][0]=\sum{min(f[to][0]-1,f[to][1],f[to][2]),to∈son_x}
f[x][1]=\sum{min(f[to][0],f[to][1]-1,f[to][2]),to∈son_x}
f[x][2]=\sum{min(f[to][0],f[to][1],f[to][2]),to∈son_x}

然后注意一下边界问题。 如果

代码语言:javascript
复制
if(c[x]) f[x][1]=1,f[x][0]=2e9,f[x][2]=1;//如果为白色
else f[x][0]=1,f[x][1]=2e9,f[x][2]=1;//如果为黑色

如果x不为叶子节点,即x>n

代码语言:javascript
复制
f[x][1]=1,f[x][0]=1;

好了鸭。。。

代码语言:javascript
复制
#include<algorithm>
#include<bitset>
#include<complex>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<iterator>
#include<limits>
#include<list>
#include<locale>
#include<map>
#include<memory>
#include<new>
#include<numeric>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<typeinfo>
#include<utility>
#include<valarray>
#include<vector>
#include<cctype>
#include<cerrno>
#include<cfloat>
#include<ciso646>
#include<climits>
#include<clocale>
#include<cmath>
#include<csetjmp>
#include<csignal>
#include<cstdarg>
#include<cstddef>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#define ll long long
using namespace std;
inline ll read(){
    ll res=0,f=1;char ch=getchar();
    while(ch<'0'ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
    return res*f;
}
inline void write(ll x){
    if(x<0) putchar('-'),x=-x;
    if(x<10) putchar(x+'0');
    else{
        write(x/10);
        putchar(x%10+'0');
    }
}
ll m,n,c[10010],in[10010],rt,f[10010][5];
vector<ll> v[10010];
void TreeDp(ll x,ll fa){
    if(x<=n){//Leaf
        if(c[x]) f[x][1]=1,f[x][0]=2e9,f[x][2]=1;
        else f[x][0]=1,f[x][1]=2e9,f[x][2]=1;
    }else f[x][1]=1,f[x][0]=1;
    for(ll i=0;i<v[x].size();i++){
        ll to=v[x][i];
        if(to==fa) continue ;
        TreeDp(to,x);
        f[x][0]+=min(f[to][0]-1,min(f[to][1],f[to][2]));
        f[x][1]+=min(f[to][0],min(f[to][1]-1,f[to][2]));
        f[x][2]+=min(f[to][0],min(f[to][1],f[to][2]));
    }
}
int main(){
    m=read();n=read();
    for(ll i=1;i<=n;i++) c[i]=read();
    for(ll i=1;i<=m-1;i++){
        ll x=read(),y=read();
        v[x].push_back(y);
        v[y].push_back(x);
        in[x]++;in[y]++;
        if(rt==0){
            if(in[x]>1) rt=x;
            else if(in[y]>1) rt=y;
        }
    }
    TreeDp(rt,0);
    write(min(f[rt][0],f[rt][1]));putchar('\n');
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-02-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 10161. 「一本通 5.2 练习 4」叶子的染色
    • 题意
      • 思路
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档