• Codeforces 1244D. Paint the Tree


    传送门

    首先如果某个点的度数大于 $2$ 那么显然无解

    然后考虑点的度数小于等于 $2$ 的情况

    发现其实是一条链

    一旦确定了链开头的两个点,后面的点的颜色都可以通过之前的点推出

    所以直接枚举即可

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=1e5+7;
    const ll INF=1e18;
    int fir[N],from[N<<1],to[N<<1],cntt;
    inline void add(int a,int b) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; }
    int n,cst[N][3],ans[3][3],col[N],pcol[N],du[N];
    vector <int> V;
    int main()
    {
        n=read();
        for(int i=0;i<3;i++)
            for(int j=1;j<=n;j++) cst[j][i]=read();
        for(int i=1;i<n;i++)
        {
            int a=read(),b=read();
            add(a,b); add(b,a);
            du[a]++; du[b]++;
        }
        for(int i=1;i<=n;i++)
            if(du[i]>2) { printf("-1
    "); return 0; }
        int rt=0; for(int i=1;i<=n;i++) if(du[i]==1) { rt=i; break; }
        int pre=rt,now=to[fir[rt]]; V.push_back(rt);
        while(du[now]>1)
            for(int i=fir[now];i;i=from[i])
            {
                int &v=to[i]; if(v==pre) continue;
                V.push_back(now); pre=now; now=v; break;
            }
        V.push_back(now);
        ll ans=INF;
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++) if(i!=j)
            {
                int len=V.size(); ll res=cst[V[0]][i]+cst[V[1]][j];
                pcol[V[0]]=i; pcol[V[1]]=j;
                for(int k=2;k<len;k++)
                {
                    for(int c=0;c<3;c++)
                        if(c!=pcol[V[k-1]]&&c!=pcol[V[k-2]]) pcol[V[k]]=c;
                    res+=cst[V[k]][pcol[V[k]]];
                }
                if(res<ans)
                    for(int k=0;k<len;k++) col[V[k]]=pcol[V[k]];
                ans=min(ans,res);
            }
        printf("%lld
    ",ans);
        for(int i=1;i<=n;i++) printf("%d ",col[i]+1);
        puts(""); return 0;
    }
  • 相关阅读:
    ASP.NET(4):多语言的解决方案
    无题
    SIP 计时器的总结(转)
    一个Sip协议栈的实现方案
    通过拦截WCF消息进行身份栈传播
    从WPF控件拖放到Winform控件的注意事项
    一个用C#操作OpenLDAP的例子
    通过定制行为拦截WCF消息
    一个基于Prism的方案的介绍
    MVVM模式下附加属性的使用
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11669434.html
Copyright © 2020-2023  润新知