zoukankan      html  css  js  c++  java
  • 洛谷 P2016 战略游戏

    题意简述简述

    求一棵树的最小点覆盖

    题解思路

    树形DP
    dp[i][0]表示第i个点覆盖以i为根的子树的最小值,且第i个点不放士兵
    dp[i][1]表示第i个点覆盖以i为根的子树的最小值,且第i个点放士兵
    $ dp[i][0] = sum{dp[son[i]][1]} ( ) dp[i][1] = sum{min(dp[son[i]][0], dp[son[i]][1])} $

    代码

    #include <cstdio>
    #include <algorithm>
    int n, x, y, k, cnt;
    int h[2000], to[4000], nxt[4000];
    int dp[2000][2];
    inline void add_edge(const int& u, const int& v)
    {
    	to[++cnt] = v;
    	nxt[cnt] = h[u];
    	h[u] = cnt;
    }
    void dfs(const int& x, const int& l)
    {
    	dp[x][1] = 1;
    	dp[x][0] = 0;
    	for (register int i = h[x]; i; i = nxt[i])
    		if (to[i] != l)
    		{
    			dfs(to[i], x);
    			dp[x][1] += std::min(dp[to[i]][1], dp[to[i]][0]);
    			dp[x][0] += dp[to[i]][1];
    		}
    }
    int main()
    {
    	scanf("%d", &n);
    	for (register int i = 1; i <= n; ++i)
    	{
    		scanf("%d%d", &x, &k);
    		for (register int i = 1; i <= k; ++i)
    		{
    			scanf("%d", &y);
    			add_edge(x, y);
    			add_edge(y, x);
    		}
    	}
    	dfs(0, -1);
    	printf("%d
    ", std::min(dp[0][0], dp[0][1]));
    }
    
  • 相关阅读:
    我的DBDA类文件
    登录时的验证码怎么写?
    phpcms 制作简单企业站的常用标签
    HTML 基础知识
    目标
    split函数的实现
    myString操作符重载
    cout中的执行顺序_a++和++a
    二叉树的层次遍历法
    树的前中序遍历_求后续遍历
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9839112.html
Copyright © 2011-2022 走看看