题目大意:一棵树,相邻两点不能同色,现有红黄蓝以及各点涂各种颜色的价值,请问涂色后最大价值是多少?
f[i][j]表示结点i涂颜色j子树的最大价值。如果i点图j色,那么儿子结点只能图另外2中颜色,取最大值即可。
最终答案是f[1][0]、f[1][1]、f[1][2]里面找。
#include <bits/stdc++.h>
#define LL long long
#define N 100005
using namespace std;
LL n, m, i, j, k, a, b, ans;
LL h[N], v[N][3], f[N][3], u[N];
struct AB{
LL a, b, n;
} d[N*2];
void cun(LL a, LL b){
d[++k].a = a, d[k].b = b;
d[k].n = h[a], h[a] = k;
}
void dfs(LL a, LL p){
LL b, c, i, j, k;
if(u[a]) return;
u[a] = 1;//已经搜过,已知该点涂色的信息
for(c=0; c<3; c++){
f[a][c] = v[a][c];
for(i=h[a]; i; i=d[i].n){
b = d[i].b;
if(b != p){//是儿子
dfs(b, a);//处理好儿子的信息
for(j=k=0; j<3; j++){//枚举儿子的颜色
if(j == c) continue;
k = max(k, f[b][j]);
}
f[a][c] += k;
}
}
}
}
int main(){
scanf("%lld", &n);
for(i=1; i<n; i++){
scanf("%lld%lld", &a, &b);
cun(a, b);
cun(b, a);
}
for(i=1; i<=n; i++){
for(j=0; j<3; j++){
scanf("%lld", &v[i][j]);
}
}
dfs(1, 0);
ans = max(f[1][0], max(f[1][1], f[1][2]));
printf("%lld\n", ans);
return 0;
}


京公网安备 11010502036488号