Codeforces Round #592 (Div. 2) D - Paint the Tree

题目链接:https://codeforces.com/contest/1244/problem/D

题意:给你一个树,让你把树上的每个节点染成三种颜色,使得任意三个互相相邻的节点颜色都不一样(意思是如果两个节点相邻,那么与这两个节点相邻的节点的颜色得和这两个节点都不一样)。这里给出每个节点染成三种颜色的代价,让我们求全部染色代价最小的方案与最小代价。

解析:如果一个点的度数大于等于3,那么肯定没有方案。所有这个树一定只是一条链,我们从度数为1的点开始dfs,把这条链存在数组里,就相当于我们只需要把数组连接三个数染成不同颜色需要付出的最小方案即可。由于情况只有3!=6种,我们可以全排列枚举,然后取最小值即可。

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+10;
ll c[3][N];
int deg[N],col[N];
vector<int>adj[N],vts;
int res[N];
void dfs(int s,int p=-1)
{
    vts.push_back(s);
    for(auto v:adj[s])
    {
        if(v!=p)
        {
            dfs(v,s);
        }
    }
}
int main()
{
    int n;
    cin>>n;
   for(int i=0;i<3;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>c[i][j];
        }
    }
    for(int i=0;i<n-1;i++)
    {
        int x,y;
        cin>>x>>y;
        x--;y--;
        deg[x]++;
        deg[y]++;
        adj[x].push_back(y);
        adj[y].push_back(x);
    }
    for(int i=0;i<n;i++)
    {
        if(deg[i]>=3)
        {
            cout<<"-1\n";
            return 0;
        }
    }
    for(int i=0;i<n;i++)
    {
        if(deg[i]==1)
        {
            dfs(i);
            break;
        }
    }
    ll ans=LLONG_MAX;
    vector<int>p={0,1,2},be;
    do{
        ll cur=0;
        for(int i=0;i<n;i++)
        {
            cur+=c[p[i%3]][vts[i]];
        }
        if(cur<ans)
        {
            ans=cur;
            be=p;
        }
    }while(next_permutation(p.begin(),p.end()));
    cout<<ans<<"\n";

    for(int i=0;i<n;i++)
    {
        res[vts[i]]=be[i%3];
    }
    for(int i=0;i<n;i++)
    {
        cout<<res[i]+1<<" ";
    }
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/hh13579/p/11688883.html