zoukankan      html  css  js  c++  java
  • D. Paint the Tree

    D. Paint the Tree

    [思路]:显然这是一个树的染色问题,那么其实根据题意,我们分析一容易发现当一个点度大于2那么肯定是无解的,有解的情况必然是一条链,那么我们只要建图找到度为1的点,跑6种情况的染色方案即可
    

    原题链接

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int MAXN = 100005;
    typedef long long LL;
    int head[MAXN], vids[MAXN], du[MAXN];
    int tot;
    void Init(){
        tot = 0;
        memset(head, -1, sizeof(head));
    }
    struct NODE{
        int u, v, next;
    }edge[MAXN << 2];
    void add(int u, int v){
        edge[tot].u = u, edge[tot].v = v, edge[tot].next = head[u], head[u] = tot ++;
    }
    LL arr[MAXN], brr[MAXN], crr[MAXN];
    LL PD(int num, int i){
        //cout << arr[i] << " " << brr[i] << " " << crr[i] << endl;
        if(num == 0)    return arr[i];
        if(num == 1)    return brr[i];
        if(num == 2)    return crr[i];
    }
    LL judge(int begin, int x, int y, int z){
        memset(vids, 0, sizeof(vids));
        int num = 0;
        vids[begin] = 1;
        LL re = 0;
        if(num % 3 == 0)    re += PD(x, begin);
        if(num % 3 == 1)    re += PD(y, begin);
        if(num % 3 == 2)    re += PD(z, begin);
        num ++;
        queue<int>que;
        while(!que.empty()){
            que.pop();
        }
        que.push(begin);
        while(!que.empty()){
            int xx = que.front();
            que.pop();
            for(int i = head[xx]; ~i; i = edge[i].next){
                if(!vids[edge[i].v]){
                    que.push(edge[i].v);
                    vids[edge[i].v] = 1;
                    if(num % 3 == 0)    re += PD(x, edge[i].v);
                    if(num % 3 == 1)    re += PD(y, edge[i].v);
                    if(num % 3 == 2)    re += PD(z, edge[i].v);
                    //cout << re << " " << edge[i].v << " " << PD(x, edge[i].v) << " " << PD(y, edge[i].v) << " " << PD(y, edge[i].v) << endl;
                    num ++;
                }
            }
        }
        return re;
    }
    void Print(int num, int n, int x, int y, int z){
        memset(vids, 0, sizeof(vids));
        int result[MAXN];
        for(int i = 0; i <= n; i ++)    result[i] = 0;
        queue<int>que;
        while(!que.empty()){
            que.pop();
        }
        que.push(num);
        vids[num] = 1;
        int flag = 0;
        if(flag % 3 == 0)   result[num] = x;
        if(flag % 3 == 1)   result[num] = y;
        if(flag % 3 == 2)   result[num] = z;
        flag ++;
        while(!que.empty()){
            int xx = que.front();
            que.pop();
            for(int i = head[xx]; ~i; i = edge[i].next){
                if(!vids[edge[i].v]){
                    que.push(edge[i].v);
                    vids[edge[i].v] = 1;
                    if(flag % 3 == 0)   result[edge[i].v] = x;
                    if(flag % 3 == 1)   result[edge[i].v] = y;
                    if(flag % 3 == 2)   result[edge[i].v] = z;
                    flag ++;
                }
            }
        }
        for(int i = 1; i <= n; i ++){
            cout << result[i] + 1 << " ";
        }
        cout << endl;
    }
    int main(){
        int n;
        ios::sync_with_stdio(false);
        cin >> n;
        for(int i = 1; i <= n; i ++)    cin >> arr[i];
        for(int i = 1; i <= n; i ++)    cin >> brr[i];
        for(int i = 1; i <= n; i ++)    cin >> crr[i];
        Init();
        for(int i = 1; i < n; i ++){
            int u, v;
            cin >> u >> v;
            add(u, v), add(v, u);
            du[u] ++, du[v] ++;
        }
        for(int i = 1; i <= n; i ++){
            if(du[i] > 2){
                cout << "-1
    ";
                return 0;
            }
        }
        int num;
        for(int i = 1; i <= n; i ++) if(du[i] == 1) {num = i; break;}
        long long re1 = judge(num, 0, 1, 2);
        long long re2 = judge(num, 0, 2, 1);
        long long re3 = judge(num, 1, 0, 2);
        long long re4 = judge(num, 1, 2, 0);
        long long re5 = judge(num, 2, 1, 0);
        long long re6 = judge(num, 2, 0, 1);
        //cout << re1 << " " << re2 << " " << re3 << " " << re4 << " " << re5 << " " << re6 << endl; 
        int nums = 1;
        if(re1 > re2){
            re1 = re2;
            nums = 2;
        }
        if(re1 > re3){
            re1 = re3;
            nums = 3;
        }
        if(re1 > re4){
            re1 = re4;
            nums = 4;
        }
        if(re1 > re5){
            re1 = re5;
            nums = 5;
        }
        if(re1 > re6){
            re1 = re6;
            nums = 6;
        }
        cout << re1 << endl;
        if(nums == 1){
            Print(num, n, 0, 1, 2);
        }
        if(nums == 2){
            Print(num, n, 0, 2, 1);
        }
        if(nums == 3){
            Print(num, n, 1, 0, 2);
        }
        if(nums == 4){
            Print(num, n, 1, 2, 0);
        }
        if(nums == 5){
            Print(num, n, 2, 1, 0);
        }
        if(nums == 6){
            Print(num, n, 2, 0, 1);
        }
        return 0;
    }
    
  • 相关阅读:
    17多校6 HDU
    E. Present for Vitalik the Philatelist 反演+容斥
    HDU
    F. Cowmpany Cowmpensation dp+拉格朗日插值
    hdu6088 组合数+反演+拆系数fft
    任意模数fft
    Codeforces Round #258 (Div. 2)E
    bzoj3670: [Noi2014]动物园
    HDU
    IO-InputStreamReader
  • 原文地址:https://www.cnblogs.com/qq136155330/p/11674656.html
Copyright © 2011-2022 走看看