P2016 战略游戏

知识点: 树形DP

原题面

题目要求:

给定一棵无根树,
花费 \(1\) 价值, 覆盖一个点 , 可以使该点为一端的所有边 被覆盖
求 将所有边全部覆盖的 最小价值

分析题意 :

  • 对题目要求进行转化 :

    • 由于一条边只有 两端点 ,
      若要覆盖将所有边 , 则每一条边至少有一个端点 被覆盖

    • 则题目要求转化为:

      给定一棵无根树,
      花费 \(1\) 价值, 可覆盖一个点
      求使所有边 至少有一个端点 被覆盖的价值

  • 对于一个 节点 :
    将其覆盖后, 只会影响其直接相邻的边,
    不直接相邻的边 不会受影响
    显然 , 可以进行树形 \(DP\) :

    • 设计状态 :
      先随意选择一个点 作为根节点
      \(\text{f[u][0/1]}\) 表示 : 以 \(u\) 节点为根的子树中, \(u\) 节点 不覆盖\(/\)覆盖 时, 满足条件的 最小价值和

    • 初始化: \(\text{f[u][1] = 1, f[u][0] = 0}\);

    • 状态转移 :

      1. 若父节点不被覆盖, 则其直接子节点必然被覆盖, 否则不合法
        则有: \(f[u][0] += \sum(f[v][1])\);
      2. 父节点被覆盖, 则其直接子节点 可以覆盖/不覆盖, 选择较小的计入贡献
        则有: \(f[u][1] += \sum min(f[v][0], f[v][1]))\)

    最后输出 \(min(f[root][0], f[root][1])\) 即可

#include <cstdio>
#include <ctype.h>
#include <vector>
#include <algorithm>
#define min std :: min
const int MARX = 1e4 + 10;
//=============================================================
struct Edge
{
	int u, v, ne;
}e[MARX << 1];
int N, num, head[MARX];
int f[MARX][2];//1自己 , 0儿子 
//=============================================================
inline int read()
{
    int s = 1, w = 0; char ch = getchar();
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') s = -1;
    for(; isdigit(ch); ch = getchar()) w = (w << 1) + (w << 3) + (ch ^ '0');
    return s * w;
}
void addedge(int u, int v)
{
	e[++ num].u = u, e[num].v = v;
	e[num].ne = head[u], head[u] = num;
}
void dfs(int u, int fa)//dfs 进行树形DP 
{
	f[u][1] = 1;//初始化 
	for(int i = head[u]; i; i = e[i].ne)
	  if(e[i].v != fa)
	  {
		dfs(e[i].v, u);//优先更新 子节点 
		//状态转移: 
		f[u][0] += f[e[i].v][1];//父节点 不覆盖 
		f[u][1] += min(f[e[i].v][0], f[e[i].v][1]);//父节点 覆盖 
	  }
}
//=============================================================
signed main()
{
	N = read();
	for(int i = 1; i <= N; i ++)//建图 
	{
	  int u = read(), m = read();
	  for(int j = 1; j <= m; j ++)
	  {
	    int v = read();
	    addedge(u, v), addedge(v, u);	
	  }
	}
	dfs(0, 0);
	printf("%d", min(f[0][0], f[0][1]));//取最小值 作为答案 
}
posted @ 2019-10-27 11:15  Luckyblock  阅读(99)  评论(0编辑  收藏  举报