zoukankan      html  css  js  c++  java
  • [洛谷3914]染色计数

    题目大意:有一颗 $N$ 个节点的树,节点用 $1,2,cdots,N$ 编号。你要给它染色,使得相邻节点的颜色不同。有 $M$ 种颜色,用 $1,2,cdots,M$ 编号。每个节点可以染 $M$ 种颜色中的若干种,求不同染色方案的数量

    题解:树形$DP$,$f_{i,j}$表示第$i$个点,涂色为$j$的方案数,$f_{i,0}$表示改点所有的涂色方案

    $$f_{i,j}=prodlimits_{k为i的儿子}(f_{k,0}-f_{k,j})(第i个点可以涂成j颜色)$$

    卡点:1.为了防止爆$int$,我采用了$0ll$加一个数,然而优先级过低,那个数先炸了。。。

    C++ Code:

    #include <cstdio>
    #define maxn 5010
    using namespace std;
    const int mod = 1000000007;
    int n, m, a, b;
    int f[maxn][maxn];
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt;
    } e[maxn << 1];
    void add(int a, int b) {
    	e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
    }
    int fa[maxn];
    void dfs(int rt) {
    	int v;
    	for (int i = head[rt]; i; i = e[i].nxt) {
    		v = e[i].to;
    		if (v != fa[rt]) {
    			fa[v] = rt;
    			dfs(v);
    			for (int j = 1; j <= m; j++) {
    				f[rt][j] = (1ll * f[rt][j] * (f[v][0] - f[v][j])) % mod;
    			}
    		}
    	}
    	for (int i = 1; i <= m; i++) if (f[rt][i] < 0) f[rt][i] += mod;
    	for (int i = 1; i <= m; i++) f[rt][0] = (f[rt][0] + f[rt][i]) % mod;
    }
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", &a);
    		for (int j = 1; j <= a; j++) scanf("%d", &b), f[i][b] = 1;
    	}
    	for (int i = 1; i < n; i++) {
    		scanf("%d%d", &a, &b);
    		add(a, b);
    		add(b, a);
    	}
    	dfs(1);
    	printf("%d
    ", f[1][0]);
    	return 0;
    }
    

      

  • 相关阅读:
    error while loading shared libraries: libhwloc.so.5: cannot open shared object file: No such file or directory
    Mac刷新DNS,修改/etc/hosts立即生效
    zxing生成识别二维码
    电脑M2接口不是磁盘0问题
    WSL
    Ubuntu安装Docker
    Win10关闭自动更新和防护
    Mysql的5种日志
    开发常用工具Windows
    log4j2高危漏洞
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9505580.html
Copyright © 2011-2022 走看看