• [洛谷] P3914 染色计数


    Description

    有一颗(N)个节点的树,节点用(1,2,cdots,N)编号。你要给它染色,使得相邻节点的颜色不同。有(M)种颜色,用(1,2,cdots,M)编号。每个节点可以染(M)种颜色中的若干种,求不同染色方案的数量除以(10^9 + 7)的余数。

    Solution

    设状态(dp[i][j])为节点(i),颜色为(j)的方案数,则有

    [dp[i][j]=sum_{k=1,k!=j}^ndp[son[i]][k](初始化dp[i][col[i]]=1) ]

    然后这个可以(dfs)的时候顺便处理(dp[i][1sim{m}])的和,就可以做到(O(nm))了。

    类似的题有P4084 [USACO17DEC]Barn Painting G

    Code

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int mod = 1e9 + 7;
    
    int n, m, tot, res, vis[5005], hd[5005], to[10005], nxt[10005], sum[5005], dp[5005][5005];
    
    int read()
    {
    	int x = 0, fl = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();}
    	return x * fl;
    }
    
    void add(int x, int y)
    {
    	tot ++ ;
    	to[tot] = y;
    	nxt[tot] = hd[x];
    	hd[x] = tot;
    	return;
    }
    
    void dfs(int x, int fa)
    {
    	for (int i = hd[x]; i; i = nxt[i])
    	{
    		int y = to[i];
    		if (y == fa) continue;
    		dfs(y, x);
    		for (int p = 1; p <= m; p ++ )
    			dp[x][p] = (1ll * dp[x][p] * (sum[y] - dp[y][p]) % mod + mod) % mod;
    	}
    	for (int p = 1; p <= m; p ++ )
    		sum[x] = (sum[x] + dp[x][p]) % mod;
    	return;
    }
    
    int main()
    {
    	n = read(); m = read();
    	for (int i = 1; i <= n; i ++ )
    	{
    		int t = read();
    		while (t -- )
    		{
    			int col = read();
    			dp[i][col] = 1;
    		}
    	}
    	for (int i = 1; i <= n - 1; i ++ )
    	{
    		int x = read(), y = read();
    		add(x, y); add(y, x);
    	}
    	dfs(1, 0);
    	for (int p = 1; p <= m; p ++ )
    		res = (res + dp[1][p]) % mod;
    	printf("%d
    ", res);
    	return 0;
    }
    
  • 相关阅读:
    java keytool证书工具使用小结(转)
    Https socket 代理
    SSL连接出现的问题
    Https 代理 sslsocket
    Https socket 连接
    linux系统一键安装phpstudy的lnmp环境
    Yii2框架实现计数器功能
    yii2框架增删改查案例
    yii2框架原生的结合框架使用的图片上传
    php将抓取的图片链接下载到本地
  • 原文地址:https://www.cnblogs.com/andysj/p/14082692.html
Copyright © 2020-2023  润新知