首页 > 其他 > 详细

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

时间:2019-12-28 17:27:50      阅读:59      评论:0      收藏:0      [点我收藏+]

?? ?? ??

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

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

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

还有这个小雪人太可爱了!
技术分享图片

#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];
    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;
}

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

原文:https://www.cnblogs.com/Herlo/p/12112283.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!