cf 1244 D. Paint the Tree

题意:

有一颗树,n个点,让你涂色,有三种颜色,每个节点每涂一种颜色都有一种成本。要求,所有连续的三个点都要有不同的颜色,并且总成本要最小。

无法满足就输出-1,否则输出成本和方案。

思路:

显然,如果有一个点的度>=3,那么肯定不满足,所以一定得是一条链。

如果头两个的颜色确定了,那么接下来的n-2个点的颜色也就确定了,

所以其实只有6种情况,模拟一下就好了。

代码:

#include <stdio.h>
#include <string.h>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
typedef long long int ll;
const double pi = acos(-1);
const int maxn = 1e5 + 10;
ll c[maxn][3],id[maxn];
int n,vis[maxn],mp[maxn][2],anss[maxn],tempp[maxn];
void add(int u,int v)
{
    if(vis[u] == 0)
        mp[u][0] = v;
    else
        mp[u][1] = v;
    vis[u]++;
}
int main()
{
    while(scanf("%d",&n) != EOF){
        for(int i = 0;i < 3;i++)
            for(int j = 1;j <= n;j++)
                scanf("%lld",&c[j][i]);
        int u,v;
        memset(vis,0,sizeof(vis));
        for(int i = 0;i < n - 1;i++){
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        int st;
        for(int i = 1;i <= n;i++){
            if(vis[i] >= 3){
                printf("-1\n");
                return 0;
            }
            if(vis[i] == 1)
                st = i;
        }
        int cnt = 0;
        id[0] = -1;
        id[++cnt] = st;
        while(cnt < n){
            u = mp[id[cnt]][0];
            v = mp[id[cnt]][1];
            if(u == id[cnt - 1])
                id[++cnt] = v;
            else
                id[++cnt] = u;
        }
        ll ans = 1e18;
        int p;
        for(int i = 0;i < 3;i++){
            for(int j = 0;j < 3;j++){
                if(i == j)
                    continue;
                tempp[1] = i;
                tempp[2] = j;
                ll temp = c[id[1]][tempp[1]] + c[id[2]][tempp[2]];
                for(int k = 3;k <= n;k++){
                    for(int h = 0;h < 3;h++){
                        if(h != tempp[k - 1] && h != tempp[k - 2]){
                            p = h;
                            break;
                        }
                    }
                    temp += c[id[k]][p];
                    tempp[k] = p;
                }
                if(ans > temp){
                    ans = temp;
                    for(int k = 1;k <= n;k++)
                        anss[id[k]] = tempp[k];
                }
            }
        }
        printf("%lld\n",ans);
        for(int i = 1;i <= n;i++)
            printf("%d ",anss[i] + 1);
        puts("");
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/InitRain/p/12409127.html