题意:树上染色,长为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