目录
- 题目
- 官方题解:
- 百度翻译
- 题解
- ac代码
题目
给多组两顶点连接,得到的图任意三个顶点都是不同的颜色,,给出各顶点染三种颜色的花费,问各店如何染,满足条件情况下,使得花费最少;
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 yy, and yy is connected by an edge with zz. 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 nn (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^{9}9), 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)(1≤c2,i≤109^{9}9), where c2,iis 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(1≤c3,i≤109^{9}9), 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 ujuj and vjvj (1≤uj,vj≤n,uj≠vj) — 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.
Otherwise, print the minimum cost of a good painting in the first line. In the second line print nn integers b1,b2,…,bn (1≤bi≤3), 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
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.
官方题解:
百度翻译
关键的观察是,如果我们确定了两个相邻顶点xx和yy的颜色,那么与xx或yy相邻的任何顶点的颜色只能是6-cx-cy。因此,我们可以确定任何边的端点的颜色(有6种可能这样做),然后对所有其他顶点进行遍历,然后再做一次遍历来检查我们是否有一幅好画。
为了避免检查我们得到的画是否好(这可能很难编码),我们可以使用这样一个事实:对于每个顶点,其所有相邻顶点的颜色应该彼此不同,并且与我们固定的顶点的颜色不同。所以,如果某个顶点的度数大于等于3,那么就没有好的画;否则我们得到的画就是好的,因为图是一个链。
题解
(1)如果满足条件,则一个顶点上最多只有两条边,所以该各顶点可连接后是一条链,所以判断若有点超过两个链接,则判为不存在;
(2)由于要找出最小花费的染色方案,则需遍历所有可能存在染色情况,找出最优方案。若为一条链,且只有三种颜色,找出头或尾(只有一个连接)确定两个颜色即可确定另一个,所以共有三种情况。
(3)注意一下,因为双向的,所以用过某条边之后,不能再用,否则会造成错误,链中存在环。
ac代码
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int M=1e5+10;
int n;
int a[4][M];
vector<int> e[M];///记录某点连接的的其他点
ll s;
int t[M], c[M], dp[M];///c[M]为(1~n)个点的颜色,t[M]是成链每一步的颜色,记录最优解各点的颜色
void dfs(int cur, int par, int step)///cur当前点,par之前出现的点(防止双向成环),链上的第几个点
{if(step>=3)t[step] = 6-t[step-1]-t[step-2];c[cur] = t[step];s+=a[t[step]][cur];for(int i=0; i<e[cur].size(); i++)///i从零开始{int nxt = e[cur][i];if(nxt==par)///防止双向成环continue;dfs(nxt, cur, step+1);}
}
int main()
{scanf("%d", &n);for(int i=1; i<=3; i++)for(int j=1; j<=n; j++)scanf("%d", &a[i][j]);for(int i=1; i<n; i++){int x, y;scanf("%d%d", &x, &y);e[x].push_back(y);e[y].push_back(x);}bool flag = true;int st = 1;for(int i=1; i<=n; i++){if (e[i].size() > 2)flag = false;if (e[i].size() == 1)st = i;}if (!flag){puts("-1");return 0;}ll ans =-1;///长整形,不能用0x3f3f3f3f来代表无穷大故为-1for(t[1] = 1; t[1]<=3; t[1]++)for(t[2] = 1; t[2]<=3; t[2]++){if(t[2]==t[1])continue;s = 0;dfs(st, 0, 1);if (ans > s||ans<0){ans = s;for(int i=1; i<=n; i++)dp[i] = c[i];}}printf("%lld\n", ans);for(int i=1; i<n; i++)printf("%d ", dp[i]);printf("%d\n",dp[n]);return 0;
}