题目链接:http://codeforces.com/contest/1244/problem/D
题目大意:给你一棵树,让你染色,一共有3种颜色.i节点涂成颜色1代价为a[i], 2:b[i], 3:c[i]。
并且树一条路径上连续的三个节点不能有颜色重复。
输出最小代价,或者不能做到-1。
思路:如果不是一条链就无法做到。很好证明。
如果是一条链。f[i][a][b]:i节点染色颜色a,它的儿子染颜***的最小代价。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
int s[100005][3];
int d[100005]={0};
LL f[100005][3][3]={0};
int vis[100005];
vector<int> v[100005], st;
int E=0;
void dfs(int u, int fa){
st.push_back(u);
if(v[u].size()==1&&fa!=-1){
E=u;
f[u][0][0]=f[u][0][1]=f[u][0][2]=s[u][0];
f[u][1][0]=f[u][1][1]=f[u][1][2]=s[u][1];
f[u][2][0]=f[u][2][1]=f[u][2][2]=s[u][2];
return;
}
for(int i=0; i<v[u].size(); i++){
int to=v[u][i];
if(to==fa){
continue;
}
else{
dfs(to, u);
for(int k1=0; k1<=2; k1++){
f[u][k1][0]=f[u][k1][1]=f[u][k1][2]=1ll<<60;
for(int k2=0; k2<=2; k2++){
for(int k3=0; k3<=2; k3++){
if(k1!=k2&&k1!=k3&&k2!=k3){
f[u][k1][k2]=min(f[to][k2][k3]+s[u][k1], f[u][k1][k2]);
}
}
}
}
}
}
}
int main()
{
int n;
scanf("%d", &n);
for(int i=0; i<3; i++){
for(int j=1; j<=n; j++){
scanf("%d", &s[j][i]);
}
}
int maxd=0, root=0;
for(int i=1; i<n; i++){
int a, b;
scanf("%d%d", &a, &b);
v[a].push_back(b);
v[b].push_back(a);
d[a]++, d[b]++;
maxd=max(d[a], maxd);
maxd=max(d[b], maxd);
}
for(int i=1; i<=n; i++){
if(d[i]==1){
root=i;
break;
}
}
//cout<<root<<endl;
if(maxd>2){
printf("-1\n");
return 0;
}
dfs(root, -1);
LL m=1ll<<60;
int x, y;
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
if(i!=j&&f[root][i][j]<m){
m=f[root][i][j];
x=i, y=j;
}
}
}
printf("%lld\n", m);
for(int i=0; i<n; i++){
vis[st[i]]=x;
int z=3-x-y;
x=y, y=z;
}
for(int i=1; i<=n; i++){
printf("%d ", vis[i]+1);
}
return 0;
}