Paint the Tree(画这棵树)

 题目

You are given a tree consisting of nn vertices. A tree is an undirected connected acyclic graph.

Example of a tree.

You have to paint each vertex into one of three colors. For each vertex, you know the cost of painting it in every color.

You have to paint the vertices so that any path consisting of exactly three distinct vertices does not contain any vertices with equal colors. In other words, let's consider all triples (x,y,z) such that x≠y,y≠z,x≠z , x is connected by an edge with y , and y is connected by an edge with z . The colours of x , y and z should be pairwise distinct. Let's call a painting which meets this condition good.

You have to calculate the minimum cost of a good painting and find one of the optimal paintings. If there is no good painting, report about it.

Input

The first line contains one integer n(3≤n≤100000) — the number of vertices.

The second line contains a sequence of integers c1,1,c1,2,…,c1,n(1≤c1,i≤109) , where c1,i is the cost of painting the i -th vertex into the first color.

The third line contains a sequence of integers c2,1,c2,2,…,c2,n(1≤c2,i≤109) , where c2,i is the cost of painting the i -th vertex into the second color.

The fourth line contains a sequence of integers c3,1,c3,2,…,c3,n(1≤c3,i≤109) , where c3,i is the cost of painting the i -th vertex into the third color.

Then (n−1) lines follow, each containing two integers uj and vj(1≤uj,vj≤n,uj≠vj) — the numbers of vertices connected by the j -th undirected edge. It is guaranteed that these edges denote a tree.

Output

If there is no good painting, print −1 .

Otherwise, print the minimum cost of a good painting in the first line. In the second line print n integers b1,b2,…,bn(1≤bi≤3) , where the i -th integer should denote the color of the i -th vertex. If there are multiple good paintings with minimum cost, print any of them.

Examples

Input

3
3 2 3
4 3 2
3 1 3
1 2
2 3

Output

6
1 3 2 

Input

5
3 4 2 1 2
4 2 1 5 4
5 3 2 1 1
1 2
3 2
4 3
5 3

Output

-1

Input

5
3 4 2 1 2
4 2 1 5 4
5 3 2 1 1
1 2
3 2
4 3
5 4

Output

9
1 3 2 1 3 

Note

All vertices should be painted in different colors in the first example. The optimal way to do it is to paint the first vertex into color 1 , the second vertex — into color 3 , and the third vertex — into color 2 . The cost of this painting is 3+2+1=6 .

 题意:给出n个节点,三种颜色可图,任意三个组成的链不能有重复颜色,所以入度大于等于3的直接break掉,输出-1;此时n个节点就构成了一条链,从入度为1的开始搜索,用邻接表存储链表顺序,dfs得到链条顺序;因为是一条链,所以只要确定前两个节点,第三个就确定了,然后第四个,第五个。。。都确定了,前两个节点三种颜色,有A(3,2)=6种排列,然后遍历这六种情况,找出最小值;

n下面的三行数据,  第i个位置表示第i个节点图该行的颜色的cost,遍历6种结果后,输出最小ans;

n-1行数据   是节点之间关系;

 思路:题意理解方式写....dfs求出节点顺序,然后solve函数遍历6次找最小;

注意:N要2*1e5+10     不然会runtime error            ans  用long long不然遇到第六组数据大,wrong answer

CODE:

#include<stdio.h>
#include<string.h>
#include<algorithm>
typedef long long ll;
const int N=2*1e5+10;
using namespace std;
ll a[10][N],degree[N],way[N],w[N],ww[N],vv[N];
ll first[N],nex[N],book[N],k=1,kk=0;
ll x=1,xx,yy,zz,ans=0x3f3f3f3f3f3f3f3f;
ll n,u,v;
void serve(ll u,ll v)
{
    w[k]=u,ww[k]=v;
    nex[k]=first[u];     ///邻接表存储
    first[u]=k;
    k++;
}
void dfs(ll q)
{
    way[x++]=q;     ///链表节点的先后顺序
    book[q]=1;
    for(ll i=first[q]; i!=-1; i=nex[i])
    {
        if(book[ww[i]])
            continue;
        dfs(ww[i]);
    }
}
void solve(int aa,int b,int c)
{
    ll sum=0;
    for(ll i=1; i<=n; i++)
    {
        ll t=way[i];
        if(i%3==1)
            sum+=a[aa][t];
        if(i%3==2)
            sum+=a[b][t];
        if(i%3==0)
            sum+=a[c][t];
    }
    if(sum<ans)
    {
        ans=sum;
        xx=aa;
        yy=b;
        zz=c;
    }
}
int main()
{
    int flag=0;
    scanf("%lld",&n);
    memset(first,-1,sizeof(first));
    memset(book,0,sizeof(book));
    for(ll i=1; i<=3; i++)
    {
        for(ll j=1; j<=n; j++)
        {
            scanf("%lld",&a[i][j]);
        }
    }
    for(ll i=1; i<n; i++)
    {
        scanf("%d %d",&u,&v);
        serve(u,v);
        serve(v,u);
        degree[u]++;
        degree[v]++;
    }
    for(ll i=1; i<=n; i++)
    {
        if(degree[i]>2)
        {
            flag=1;
            break;
        }
    }
    if(flag)
        printf("-1\n");
    else
    {
        for(int i=1; i<n; i++)
            if(degree[i]==1)
            {
                dfs(i);
                solve(1,2,3);///六中情况遍历
                solve(1,3,2);
                solve(2,1,3);
                solve(3,1,2);
                solve(3,2,1);
                solve(2,3,1);
                printf("%lld\n",ans);///最小价值
                for(int i=1; i<=n; i++)///第t个节点图上第xx(yy,zz)种颜色
                {
                    int t=way[i];
                    if(i%3==1)
                        vv[t]=xx;
                    if(i%3==2)
                        vv[t]=yy;
                    if(i%3==0)
                        vv[t]=zz;
                }
                for(ll i=1; i<n; i++)
                    printf("%d ",vv[i]);
                printf("%d\n",vv[n]);
                break;
            }
    }
    return 0;
}

 我太难了~哭唧唧~

生活不易,小猪猪叹息~=(´ο`*)))唉~

加油丫,你是最棒的!!~

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵩韵儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值