• 解题报告:CF1244D


    题目链接;CF1244D Paint the Tree
    暴毙。
    手玩一下,就会发现只有树是链的情况下才有解,就可以搞到序列上做运算了。
    然后莽了一发(dp),然后就炸了,原因是一个点的颜色受前两个点控制,而不是只有上一个。
    其实确定序列后只有(3!=6)中选法,由于第三个是前两个控制的,且是唯一的,然后就行了。
    最后把每个点和编号对应起来就好了。
    效率是(mathcal O(n))的,可以通过本题。
    下面是我睿智的代码与正解的集合:

    (Code)

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define ll long long
    #define MAXN 100005 
    #define INF 1ll<<61
    int deg[MAXN];
    struct node
    {
    	int to,nxt;
    }e[MAXN<<1];
    int head[MAXN],cnt=0;
    void add(int l,int r)
    {
    	e[++cnt].to=r;
    	e[cnt].nxt=head[l];
    	head[l]=cnt;
    }
    ll f[5][MAXN],a[5][MAXN],sum,maxn;
    int id[MAXN],ans[MAXN];
    int c=0;
    void dfs(int cur,int fa)
    {
    	f[0][++c]=a[0][cur];
    	f[1][c]=a[1][cur];
    	f[2][c]=a[2][cur];
    	id[c]=cur;
    	for(int i=head[cur];i;i=e[i].nxt) if(fa!=e[i].to) dfs(e[i].to,cur);
    }
    int n,u,v;
    int rt[MAXN],rl;
    //我是真的菜 
    int main()
    {
    	#define read(x) scanf("%d",&x)
    	#define read_l(x) scanf("%lld",&x)
    	read(n);
    	for(int i=1;i<=n;i++) read_l(a[0][i]);
    	for(int i=1;i<=n;i++) read_l(a[1][i]);
    	for(int i=1;i<=n;i++) read_l(a[2][i]);
    	for(int i=1;i<n;i++)
    	{
    		read(u),read(v);
    		add(u,v),add(v,u);
    		deg[u]++,deg[v]++;
    		if(deg[u]>=3||deg[v]>=3)
    		{
    			printf("%d
    ",-1);
    			return 0;
    		}
    	}
    	for(int i=1;i<=n;i++) if(deg[i]==1){dfs(i,i);break;}
    	/*for(int i=1;i<=n;i++)
    	{
    		dp[0][i]=dp[1][i]=dp[2][i]=INF;
    		for(int j=0;j<=2;j++)
    		{
    			for(int k=0;k<=2;k++)
    			{
    				if(j==k) continue;
    				if(dp[k][i-1]+f[j][i]<dp[j][i]) dp[j][i]=dp[k][i-1]+f[j][i],t[j][i]=k;
    			}
    		}
    	}*/
    	int op=0; 
    	maxn=INF;
    	for(int i=1;i<=3;i++)
    	{
    		for(int j=1;j<=3;j++)
    		{
    			if(i==j) continue;
    			op++;
    			rt[1]=i,rt[2]=j,sum=f[i-1][1]+f[j-1][2];
    			for(int k=3;k<=n;k++) rt[k]=6-rt[k-1]-rt[k-2],sum+=f[rt[k]-1][k];
    			if(sum<maxn) maxn=sum,rl=op;
    		}	
    	} 
    	printf("%lld
    ",maxn);
    	int co=0;
    	for(int i=1;i<=3;i++)
    	{
    		for(int j=1;j<=3;j++)
    		{
    			if(i==j) continue;
    			co++;
    			if(co==rl)
    			{
    				ans[id[1]]=i,ans[id[2]]=j,rt[1]=i,rt[2]=j,sum=f[i-1][1]+f[j-1][2];
    				for(int k=3;k<=n;k++) ans[id[k]]=6-rt[k-1]-rt[k-2],rt[k]=ans[id[k]],sum+=f[rt[k]-1][k];
    				break;
    			}
    		}
    	}
    	/*if(dp[0][n]<dp[1][n]&&dp[0][n]<dp[2][n])
    	{
    		printf("%lld
    ",dp[0][n]);
    		ans[id[n]]=1;
    		int k=0;
    		for(int i=n;i>=2;i--) ans[id[i-1]]=t[k][i]+1,k=t[k][i];
    	}
    	else if(dp[1][n]<dp[0][n]&&dp[1][n]<dp[2][n])
    	{
    		printf("%lld
    ",dp[1][n]);
    		ans[id[n]]=2;
    		int k=1;
    		for(int i=n;i>=2;i--) ans[id[i-1]]=t[k][i]+1,k=t[k][i];
    	}
    	else
    	{
    		printf("%lld
    ",dp[2][n]);
    		ans[id[n]]=3;
    		int k=2;
    		for(int i=n;i>=2;i--) ans[id[i-1]]=t[k][i]+1,k=t[k][i];
    	}*/
    	for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    	return 0;
    } 
    
  • 相关阅读:
    C#读取Excel日期时间
    软件需求3个层次――业务需求、用户需求和功能需求
    软件开发中的基线
    软件开发过程(CMMI/RUP/XP/MSF)是与非
    第1章项目初始.pdf
    计算机鼓轮
    概念模型,逻辑模型,物理模型
    第0章项目管理概述.pdf
    C#中提供的精准测试程序运行时间的类Stopwatch
    Installing and configuring OpenSSH with pam_ldap for RedHat Enterprise Linux3
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12629373.html
Copyright © 2020-2023  润新知