zoukankan      html  css  js  c++  java
  • 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
    ");
                    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
    ",ans);
            for(int i = 1;i <= n;i++)
                printf("%d ",anss[i] + 1);
            puts("");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Windows环境下Unicode编程总结
    我的CS脚本autoexec.cfg
    完成端口与高性能服务器程序开发[引用]
    调用未知DLL中的导出函数
    兼容Vista 赛门铁克公测新杀毒软件
    I Love You的真正含义
    码根码
    木马经典十大藏身地点大搜查
    Windows调试器及不同平台符号包下载地址(收集)
    “千般路”与“磨豆腐”
  • 原文地址:https://www.cnblogs.com/InitRain/p/12409127.html
Copyright © 2011-2022 走看看