Codeforces Round #592 (Div. 2) D,E

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)(x,y,z) such that xy,yz,xzx≠y,y≠z,x≠z, xx is connected by an edge with yy, and yy is connected by an edge with zz. The colours of xx, yy and zz 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(3n100000) — the number of vertices.

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

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

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

Then (n1) lines follow, each containing two integers uand vjvj (1uj,vjn,ujvj) — the numbers of vertices connected by the jj-th undirected edge. It is guaranteed that these edges denote a tree.

Output

If there is no good painting, print 1−1.

Otherwise, print the minimum cost of a good painting in the first line. In the second line print nn integers b1,b2,,bn (1bi3), where the ii-th integer should denote the color of the ii-th vertex.

If there are multiple good paintings with minimum cost, print any of them.

Examples
input
Copy
3
3 2 3
4 3 2
3 1 3
1 2
2 3
output
Copy
6
1 3 2 
input
Copy
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
Copy
-1
input
Copy
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
Copy
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

 

 

题意:有各个节点涂成三种颜色中的一种的花费,每个节点相邻的节点颜色不能一样(包括此节点),求存在的最小花费。不存在则输出-1;

思路:可以推出,如果一个节点有三条边连向外面,那么包括它一共有四个点,这是一定不满足的,所以一个节点最多两条边,这不就是一条链吗?

我们找到这条链的任意一个起点,然后确定这条链开头两个点的颜色。

其他点的颜色可以一一推出,故只需要六个dfs就可以得出最小花费。

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define pb push_back
const int N=100010;
int vis[N];
long long ans;
vector<int> vec[N];
vector<int> pass;
int color[7][4]={{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,1,2},{3,2,1}};
int n,a,b;
int flag=1;
int aa[N];
int choice[4][N];
void dfs(int x)
{
    vis[x]=1;
    pass.pb(x);
    for(int i=0;i<vec[x].size();i++)
    {
        int temp=vec[x][i];
        if(!vis[temp])
        {
            dfs(temp);
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=n;j++)
            scanf("%d",&choice[i][j]);
    }
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&a,&b);
        vec[a].pb(b);
        vec[b].pb(a);
    }
    for(int i=1;i<=n;i++)
    {
        if(vec[i].size()>2)
        {
            flag=0;
            printf("-1\n");
            break;
        }
    }
    if(flag)
    {
        for(int i=1;i<=n;i++)
        {
            if(vec[i].size()==1)//找到了链的开头.
            {
                dfs(i);
                break;
            }
        }
        long long minn=1e18;
        int tt,pp;
        /*for(int i=0;i<pass.size();i++)
            printf("%d%c",pass[i],i==pass.size()-1?'\n':' ');*/
        for(int i=0;i<6;i++)
        {
            ans=0;
            for(int j=0;j<pass.size();j++)
            {
                ans+=choice[color[i][j%3]][pass[j]];
            }
            if(ans<minn)
            {
                minn=ans;
                tt=i;
            }
        }
        printf("%lld\n",minn);
        for(int i=0;i<n;i++)
        {
            aa[pass[i]]+=color[tt][i%3];
        }
        for(int i=1;i<=n;i++)
        {
            printf("%d%c",aa[i],i==n?'\n':' ');
        }
    }
    return 0;
}
View Code

 

 E题,直接从左右更新即可

#include<stdio.h>
#include<math.h>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
#define ll long long
ll n,k;
const int N=100010;
ll sum[N];
ll a[N];
ll ans,endans;
int main()
{
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    for(int i=1;i<=n/2;i++)
    {
        ans=(a[i+1]-a[i]+a[n-i+1]-a[n-i])*i;
        if(k>=ans)
        {
            k-=ans;
        }
        else
        {
            endans=a[n-i+1]-a[i]-k/i;
            printf("%lld\n",endans);
            return 0;
        }
    }
    printf("0\n");
    return 0;
}
View Code

 

 

 

posted @ 2019-10-15 16:14  _HonEy  阅读(103)  评论(0编辑  收藏  举报