Codeforces Round #592 (Div. 2) D - Paint the Tree(树上染色)

🧒 🧒 🧒

题意:树上染色,长为3的一段链上必须包含三种颜色,问你最小花费

1,若存在度≥ 2 的结点无法染色(加上父节点有三个点连在同一个点上,无法染色)

2, 有效情况只可能是一条链,找到链的端点,然后枚举六种染色情况即可

这个小雪人太可爱了!
Happy New Year !!

#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0, i##len = (int)(n); i < i##len; ++i)
#define rpp(i, n) for (int i = 1, i##len = (int)(n); i <= i##len; ++i)
vector<int>c[3];
vector<int>mp[MAXN];
string s[6]={"123","132","213","231","312","321"};
vector<int> num;
ll dfs(int x,int i,int j,int fa,ll now)
{
    for(int v:mp[x])
    {
        if(v==fa) continue;
        ll tmp=dfs(v,i,(j+1)%3,x,now);
        now+=tmp;
    }
    now+=c[s[i][j]-'0'-1][x-1];//树(链)上??DP从下到上,要后更新
    return now;
}
void dfs2(int x,int i,int j,int fa)
{
    num[x]=s[i][j]-'0';
    for(int v:mp[x])
    {
        if(v==fa) continue;
        dfs2(v,i,(j+1)%3,x);
    }
}
int main()
{
    int n;cin>>n;
    rep(i,3) c[i].resize(n),cin>>c[i];
    int flag=1;
    rep(i,n-1) 
    {
        int x,y;cin>>x>>y;
        mp[x].push_back(y),mp[y].push_back(x);
        if(mp[x].size()>=3||mp[y].size()>=3) flag=0;
    }
    if(flag==0) return puts("-1"),0;

    //枚举六种方案
    int st;
    rpp(i,n) if(mp[i].size()==1) {st=i;break;}
    ll ans=-1;
    int tag;
    rep(i,6)
    {
        ll tmp=dfs(st,i,0,0,0);
        if(ans==-1) ans=tmp,tag=i;
        else if(tmp<ans) tag=i,ans=tmp;
    }
    cout<<ans<<endl;
    num.resize(n+1);
    dfs2(st,tag,0,0);
    rpp(i,n) cout<<num[i]<<" ";
    cout<<"\n";
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值