zoukankan      html  css  js  c++  java
  • 洛谷2016 战略游戏 (0/1状态的普通树形Dp)

    题意:

    给出一个树,覆盖树上某一个点的花费为w[i],求树上每一条边至少有一个点覆盖的最小花费。

    细节:

    1.一条边的两端可以均被覆盖,但是不能存在一条边的两端都不被覆盖。
    2.可能存在

    分析:

    对于一对儿子和父亲节点来说,要么儿子覆盖父亲不覆盖,父亲覆盖儿子不覆盖,或者是两者均被覆盖,所以不难发现对于父亲节点来说,若其被覆盖,则它的所有子孙可以被覆盖也可以不被覆盖,若其不被覆盖,则它的子孙必须可以被全部覆盖。

    所以状态变得显然:dp[u][0/1] 表示节点 u 是否被覆盖的最小花费
    再根据上方的分析条件转移如下:
    dp[u][1] = ∑ min( dp[v][0] , dp[v][1] )
    dp[u][0] = ∑ dp[v][1]

    代码

    #include<bits/stdc++.h>
    #define MAXN 1505
    using namespace std;
    
    int f[MAXN][2], n;
    vector<int> Right[MAXN];
    
    void dfs(int u, int fa){
    	f[u][0]=0, f[u][1]=1;
    	for (int i=0; i<Right[u].size(); i++) {
    		int v=Right[u][i];
    		if (v==fa) continue;
    		dfs(v, u);
    		f[u][0]+=f[v][1];
    		f[u][1]+=min(f[v][0], f[v][1]);
    	}
    }
    
    int main(){
    	scanf("%d", &n);
    	for (int i=1, x, num; i<=n; i++) {
    		scanf("%d%d", &x, &num);
    		for (int j=1, y; j<=num; j++) {
    			scanf("%d", &y);
    			Right[x].push_back(y);
    			Right[y].push_back(x);
    		}
    	}
    	dfs(1, -1);
    	printf("%d\n", min(f[root][0], f[root][1]));
    	return 0;
    }
    

    Ps:

    此题与 DAY2T344 分算法十分雷同,但是我死在了考场的一线上……

  • 相关阅读:
    TCP 和 UDP 的区别
    python--各种锁机制归纳整理
    七牛的配置
    全文检索的配置
    记一则css3计算
    C# 生成序号不足补0
    JavaScript Post提交数据并跳转到页面(模拟Form表单提交)
    Swift 修改UITextField.Placeholder颜色
    Swift 延迟运行代码
    Swift 动画片段
  • 原文地址:https://www.cnblogs.com/xiannvzuimei/p/9961319.html
Copyright © 2011-2022 走看看