zoukankan      html  css  js  c++  java
  • [CQOI2009]叶子的染色

    首先,选择任意一个度数大于(1)的节点为根的最优的答案都是固定的,具体证明这里不加赘述。

    我们仔细研究,他只要求根节点到叶子节点的最后一个有色节点的颜色。我们对第(x)号节点染色,意味着我们把所有它子树中的叶子节点最近的一个有色节点的颜色就发生了改变。显然,儿子越多的节点性价比越高。

    因此,我们定义(dp_{i,0/1})为第(i)号节点染成第(j)种颜色的最小花费,那么对于(j)号节点是他的儿子,可以把他的儿子染成异色,也可以让儿子的颜色与他一致,有转移方程如下:

    (dp_{i,0}) += (min(dp_{j,0} - 1 , dp_{j,1}))

    (dp_{i,1}) += (min(dp_{j,1} - 1 , dp_{j,0}))

    ```cpp
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int MAXN = 1e4 + 5;
    int head[MAXN] , to[MAXN << 1] , nxt[MAXN << 1] , cnt , n , m;
    int c[MAXN] , dp[MAXN][2];
    void add(int x , int y){nxt[++cnt] = head[x];head[x] = cnt;to[cnt] = y;}
    void read(int &x) {
    	int f = 1;x = 0;char s = getchar();
    	while(s < '0' || s > '9') {if(s == '-') f = -1;s = getchar();}
    	while(s >= '0' && s <= '9') {x = (x << 3) + (x << 1) + s - '0';s = getchar();}
    	x *= f;
    }
    void dfs(int x , int fa) {
    	if(x <= n) {
    		dp[x][c[x]] = 1; // 染上的花费
    		dp[x][!c[x]] = 1e9; // 不能染这种颜色,设为无穷大
    		return;
    	}
    	dp[x][0] = dp[x][1] = 1;
    	for (int i = head[x]; i; i = nxt[i]) {
    		if(to[i] == fa) continue;
    		dfs(to[i] , x);
    		dp[x][0] += min(dp[to[i]][0] - 1 , dp[to[i]][1]);
    		dp[x][1] += min(dp[to[i]][0] , dp[to[i]][1] - 1);
    		//转移,如上
        }
    }
    int main() {
    	read(m);read(n);
    	for (int i = 1; i <= n; ++i) read(c[i]);
    	for (int i = 1; i < m; ++i) {
    		int x , y;
    		read(x);read(y);
    		add(x , y);
    		add(y , x);
    	}
    	dfs(m , m);//姑且选m为根节点
    	printf("%d" , min(dp[m][0] , dp[m][1]));
    	return 0;
    }
    
    ```
  • 相关阅读:
    Unity3D游戏-愤怒的小鸟游戏源码和教程(一)
    Unity插件-ShareSDK使用指南
    Unity 3D开发-C#脚本语言的一些基础用法
    Shader的函数公式以及使用的场景
    Shader的基本用法和语法结构
    iTween的用法总结
    Unity 3D游戏-消消乐(三消类)教程和源码
    Unity 3D游戏-NPC对话系统With XML
    XML教程、语法手册、数据读取方式大全
    ReSharper2017.3的列对齐、排版格式、列对齐错误的修复
  • 原文地址:https://www.cnblogs.com/Reanap/p/13423244.html
Copyright © 2011-2022 走看看