zoukankan      html  css  js  c++  java
  • Luogu3914 染色计数

    Description

    link

    给定一棵 (n) 个点的树,树上的每个点可以涂 (m) 种颜色的中的几种

    规定相邻的两个点涂的颜色不一样,求方案数

    (n,m le 5000)

    Solution

    定义状态:

    (f_{x,y}) 为点 (x) 涂颜色 (y) 的时候的子树里的方案数

    那么答案就是

    [sum_{i=1&&iin {col_1}}^m f_{1,i} ]

    转移就是把每个儿子上面颜色不一样的求和乘起来

    我们发现这个做法是 (O(n^3)) 的,并不能通过

    然后我们优化一下这个转移,把每个儿子的方案求个和

    对应乘的时候直接减掉那个颜色就成了

    Code

    #include<bits/stdc++.h>
    using namespace std;
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int mod=1e9+7,N=5010;
    	int n,m,head[N],cnt;
    	struct node{
    		int to,nxt;
    	}e[N<<1];
    	inline void add(int u,int v)
    	{
    		e[++cnt].to=v; e[cnt].nxt=head[u];
    		return head[u]=cnt,void();
    	}
    	int sum[N],f[N][N];
    	inline void dfs(int x,int fa)
    	{
    		for(int i=head[x];i;i=e[i].nxt)
    		{
    			int t=e[i].to; 
    			if(t==fa) continue; dfs(t,x);
    			for(int j=1;j<=m;++j) 
    			{
    				f[x][j]=1ll*f[x][j]*((sum[t]-f[t][j]+mod)%mod)%mod;	
    			}
    		}
    		for(int i=1;i<=m;++i) sum[x]=(sum[x]+f[x][i])%mod; 
    		return ;
    	}
    	signed main()
    	{
    		n=read(); m=read();
    		for(int tmp,i=1;i<=n;++i)
    		{
    			tmp=read(); while(tmp--) f[i][read()]=1;
    		}
    		for(int i=1,u,v;i<n;++i) u=read(),v=read(),add(u,v),add(v,u);
    		dfs(1,0); printf("%d
    ",sum[1]);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    【转载】Myeclipse如何自动创建hibernate
    win7 64位mysql安装及navicat 解压版
    NuGet套件还原步骤(以vs2012为例)
    Html.DropDownListFor() 二级联动 ($.getJSON)
    ModelState验证部分属性
    asp.net mvc发送邮件
    SpringBoot的热部署
    SpringBoot 入门demo
    集群、负载均衡、微服务、分布式的概念
    SpringBoot 简介
  • 原文地址:https://www.cnblogs.com/yspm/p/13234381.html
Copyright © 2011-2022 走看看