题目链接
https://codeforces.com/contest/1244/problem/D
Paint the Tree
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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 x≠y,y≠z,x≠zx≠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 nn (3≤n≤100000)(3≤n≤100000) — the number of vertices.
The second line contains a sequence of integers c1,1,c1,2,…,c1,nc1,1,c1,2,…,c1,n (1≤c1,i≤109)(1≤c1,i≤109), where c1,ic1,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,nc2,1,c2,2,…,c2,n (1≤c2,i≤109)(1≤c2,i≤109), where c2,ic2,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,nc3,1,c3,2,…,c3,n (1≤c3,i≤109)(1≤c3,i≤109), where c3,ic3,i is the cost of painting the ii-th vertex into the third color.
Then (n−1)(n−1) lines follow, each containing two integers ujuj and vjvj (1≤uj,vj≤n,uj≠vj)(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−1.
Otherwise, print the minimum cost of a good painting in the first line. In the second line print nn integers b1,b2,…,bnb1,b2,…,bn (1≤bi≤3)(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 11, the second vertex — into color 33, and the third vertex — into color 22. The cost of this painting is 3+2+1=63+2+1=6.
这一题思路比较清晰,但是代码量比较大。
首先根据题意可得最终符合条件的图为一条链,因此只要存在度大于2的点即为不存在,输出-1。
这个链可以采用链式前向星储存。之后采用dfs,将其连起来。
然后可以发现只要确定了这条链的前两个点,便能确定整条链的情况。所以我们可以采用暴力遍历这六种方案,取其中最小的那一个便可。
#define _CRT_SECURE_NO_DEPRECATE
#include<cstdio>
#include<stdlib.h>
#include<algorithm>
#include<string>
#include<iostream>
#include<unordered_map>
#include<stack>
#include<math.h>
#include<set>
#include<map>
#include<queue>
#include<cstring>
#include<deque>
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define lowbits(x) x&(-x)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int N = 2e5 + 10;
ll a[4][N];
int degree[N];
int head[N], to[N], nex[N];
bool vis[N];
int tree[N];
int cnt;
int xx, yy, zz;
void add(int u, int v) { //链式前向星存图
to[++cnt] = v;
nex[cnt] = head[u];
head[u] = cnt;
}
int cnt1;
int n;
void dfs(int x) { //建链
tree[++cnt1] = x;
vis[x] = 1;
for (int i = head[x]; i; i = nex[i]) {
if (vis[to[i]] == true) {
continue;
}
else {
dfs(to[i]);
}
}
}
ll minn = 1e18;
void solve(int x, int y, int z) {
ll sum = 0;
for (int i = 1; i <= n; i++) {
int t = tree[i];
if (i % 3 == 1) {
sum += a[x][t];
}
else if (i % 3 == 2) {
sum += a[y][t];
}
else if (i % 3 == 0) {
sum += a[z][t];
}
}
if (sum < minn) {
minn = sum;
xx = x;
yy = y;
zz = z;
}
}
int ans[N];
int main() {
cin >> n;
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
}
}
bool flag = 0;
for (int i = 1; i <= n - 1; i++) {
int u, v;
cin >> u >> v;
degree[u]++, degree[v]++;
if (degree[u] >= 3 || degree[v] >= 3) {
flag = 1;
}
add(u, v);
add(v, u);
}
if (flag) {
cout << -1 << endl;
return 0;
}
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(2, 3, 1);
solve(3, 1, 2);
solve(3, 2, 1);
break;
}
}
cout << minn << endl;
for (int i = 1; i <= n; i++) {
int t = tree[i];
if (i % 3 == 1) {
ans[t] = xx;
}
else if (i % 3 == 2) {
ans[t] = yy;
}
else if (i % 3 == 0) {
ans[t] = zz;
}
}
for (int i = 1; i <= n; i++) {
cout << ans[i] << " ";
}
cout << endl;
return 0;
}