zoukankan      html  css  js  c++  java
  • codeforces1244——D.Paint the Tree(dfs)

    原题链接
    题意:
    给定一棵树,每个节点都可以涂三种颜色,分别有不同的代价。现在要求你对一棵树进行涂色,要求任意相邻的三个点的颜色都不同,求最小代价和任意一种涂色方案,没有方案输出-1
    思路:
    首先,如果一个节点的度数大于3那就必然不能成功涂色。
    假设A的出度点是B,C,D.那么无论怎么组合,都无法使得任意三个点的颜色相同。
    所以这棵树只有由度数为1和2的点构成的时候才可以被涂色,这时候就相当于一条链。
    从链的一端开始涂色,当前两个点的颜色确定时,第三个点的颜色也会确定,相继会确定所有点的颜色。我们只需要枚举前两个点的涂色方案,从而计算出每一种涂色方案的权值,记录最小值即可。
    代码:

    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<ll,ll>PLL;
    typedef pair<int,int>PII;
    typedef pair<double,double>PDD;
    #define I_int ll
    inline ll read()
    {
        ll 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*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    char F[200];
    inline void out(I_int x)
    {
        if (x == 0) return (void) (putchar('0'));
        I_int tmp = x > 0 ? x : -x;
        if (x < 0) putchar('-');
        int cnt = 0;
        while (tmp > 0)
        {
            F[cnt++] = tmp % 10 + '0';
            tmp /= 10;
        }
        while (cnt > 0) putchar(F[--cnt]);
        //cout<<" ";
    }
    ll ksm(ll a,ll b,ll p)
    {
        //a%=p;
        ll res=1;
        while(b)
        {
            if(b&1)res=1ll*res*a%p;
            a=1ll*a*a%p;
            b>>=1;
        }
        return res;
    }
    const int inf=0x3f3f3f3f;
    const ll mod=1e9+7;
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const int maxn=2e5+100,maxm=3e5+7,N=1e6+7;
    const double PI = atan(1.0)*4;
    vector<int>g[maxn];
    ll col[4][maxn];
    int n,din[maxn];
    int tmp[maxn],res[maxn];
    ll ans=-1;
    int t[maxn];
    ///dfs(1,s,-1);
    void dfs(int u,int now,int fa){
        if(u>=3) t[u]=6-t[u-1]-t[u-2];
        tmp[now]=t[u];
        ans+=col[tmp[now]][now];
        for(auto t:g[now]){
            if(t==fa) continue;
            dfs(u+1,t,now);
        }
    }
    int main()
    {
        n=read();
        for(int i=1;i<=3;i++)
            for(int j=1;j<=n;j++)
               col[i][j]=read();
        bool flag=1;
        for(int i=1;i<n;i++){
            int u=read(),v=read();
            g[u].push_back(v);
            g[v].push_back(u);
            din[u]++;din[v]++;
            if(din[u]>2||din[v]>2) flag=0;
        }
        if(!flag) puts("-1");
        else{
            int s=-1;
            for(int i=1;i<=n;i++)
                if(din[i]==1){///从头开始遍历
                    s=i;break;
                }
            ll minn=INF;
            for(t[1]=1;t[1]<=3;t[1]++)///枚举前两个点的涂色方案
                for(t[2]=1;t[2]<=3;t[2]++)
                    if(t[1]!=t[2]){
                        ans=0;
                        dfs(1,s,0);
                        if(minn>ans){
                            minn=ans;
                            for(int i=1;i<=n;i++) res[i]=tmp[i];///更新答案
                        }
                            
                    }
            printf("%lld
    ",minn);
            for(int i=1;i<=n;i++)
                printf("%d ",res[i]);
        }
        return 0;
    }
    

    参考

  • 相关阅读:
    linux下启动和关闭网卡命令及DHCP上网
    python 编码问题
    paddlepaddle
    Convolutional Neural Network Architectures for Matching Natural Language Sentences
    deep learning RNN
    Learning Structured Representation for Text Classification via Reinforcement Learning 学习笔记
    Python IO密集型任务、计算密集型任务,以及多线程、多进程
    EM 算法最好的解释
    tensorflow 调参过程
    tensorflow 学习纪录(持续更新)
  • 原文地址:https://www.cnblogs.com/OvOq/p/14853084.html
Copyright © 2011-2022 走看看