题目描述

Bob喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的办法。现在他有个问题。他要建立一个古城堡,城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路。注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。

请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵。

输入格式

输入文件中数据表示一棵树,描述如下:

第一行 N,表示树中结点的数目。

第二行至第N+1行,每行描述每个结点信息,依次为:该结点标号i,k(后面有k条边与结点I相连),

接下来k个数,分别是每条边的另一个结点标号r1,r2,...,rk。

对于一个n(0 < n <= 1500)个结点的树,结点标号在0到n-1之间,在输入文件中每条边只出现一次。

输出格式

输出文件仅包含一个数,为所求的最少的士兵数目。


分析题目。

如果我们在节点u放一个士兵,那么跟u相连的所有边都会被望到。这是题目中的原话,但我们不应该只拘束于它本身。我们可以进行适当的拓展,然后我们可以进一步得出这样一个结论:当我们在u放了一个士兵以后,与u相连的其他节点就可以被望到,也就是说这些节点可放可不放。而如果我们不在u放士兵,那么其它点就必须放。

设dp(i,0/1)表示以i为根的子树中士兵数量的最小值,0代表i不放士兵,1代表放。由于城堡中的路是一棵树,所以最小值显然具有传递性,具体为从儿子传给父亲。所以我们可以用动态规划来做这题。设u有k个儿子,那么状态转移方程如下:

\[dp[u][0]=\sum_{i=1}^{q}dp[son[i]][1];\\
dp[u][1]=\sum_{i=1}^{q}Min(dp[son[i]][0],dp[son[i]][1]);
\]

初始化dp(x,0)=0,dp(x,1)=1。

显然一遍dfs就可以做完这个过程,时间复杂度为O(N)。

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1501
using namespace std; struct edge{
int to,next;
edge(){}
edge(const int &_to,const int &_next){
to=_to,next=_next;
}
}e[maxn<<1];
int head[maxn],k;
int dp[maxn][2],n; inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
inline void add(const int &u,const int &v){ e[k]=edge(v,head[u]); head[u]=k++; } void dfs(int u,int pre){
dp[u][0]=0,dp[u][1]=1;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==pre) continue;
dfs(v,u);
dp[u][0]+=dp[v][1];
dp[u][1]+=min(dp[v][0],dp[v][1]);
}
} int main(){
memset(head,-1,sizeof head);
n=read();
for(register int i=1;i<=n;i++){
int u=read()+1,cnt=read();
while(cnt--){ int v=read()+1; add(u,v),add(v,u); }
} memset(dp,0x3f,sizeof dp);
dfs(1,0);
printf("%d\n",min(dp[1][0],dp[1][1]));
return 0;
}

luoguP2016 战略游戏的更多相关文章

  1. [luoguP2016] 战略游戏(DP)

    传送门 f[i][0]表示不选当前节点,当前节点的所有儿子节点都选f[i][1]表示选当前节点,儿子节点可选可不选 #include <cstdio> #include <cstri ...

  2. D3D游戏编程系列(三):自己动手编写即时战略游戏之寻路

    说起即时战略游戏,不得不提的一个问题是如何把一个物体从一个位置移动到另一个位置,当然,我说的不是瞬移,而是一个移动的过程,那么在这个移动的过程中我们如何来规划路线呢,这就不得不提到寻路了. 我所了解到 ...

  3. 【BZOJ3924】幻想乡战略游戏(动态点分治)

    [BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...

  4. 『战略游戏 最大利润 树形DP』

    通过两道简单的例题,我们来重新认识树形DP. 战略游戏(luoguP1026) Description Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要 ...

  5. LOJ2135 「ZJOI2015」幻想乡战略游戏

    题意 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和 ...

  6. LOJ #2135. 「ZJOI2015」幻想乡战略游戏

    #2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...

  7. BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)

    Description 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着 ...

  8. [SDOI2018]战略游戏 圆方树,树链剖分

    [SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...

  9. 洛谷P2016战略游戏

    传送门啦 战略游戏这个题和保安站岗很像,这个题更简单,这个题求的是士兵人数,而保安站岗需要求最优价值. 定义状态$ f[u][0/1] $ 表示 $ u $ 这个节点不放/放士兵 根据题意,如果当前节 ...

随机推荐

  1. Jupyter Notebook在多个虚拟环境配置与使用

    1 问题描述 使用Anaconda配置了包括Pytorch.Tensorflow等多个虚拟环境后,依然无法使用Jupyter Notebook选择不同的虚拟环境运行代码,问题如下图所示. 2 解决方法 ...

  2. 如何使用Pytest进行自动化测试

    为什么需要自动化测试 自动化测试有很多优点,但这里有3个主要的点 可重用性:不需要总是编写新的脚本,除非必要,即使是新的操作系统版本也不需要编写脚本. 可靠性:人容易出错,机器不太可能.当运行不能跳过 ...

  3. Spring Cloud正式移除Hystrix、Zuul等Netflix OSS组件

    1. 前言 2020-12-22日Spring官方博客宣布,Spring Cloud 2020.0.0正式发布.2020.0.0是第一个使用新的版本号命名方案的Spring Cloud发行版本.在此之 ...

  4. 【基础】Linux系统的运行级别

    1.系统运行级别的配置文件 什么是运行级呢?简单的说,运行级就是操作系统当前正在运行的功能级别. 它让一些程序在一个级别启动,而另外一个级别的时候不启动. Linux系统的有效登录模式有0~9共十种, ...

  5. java日常工作错误总结

    1.将一个新的项目拷贝到另一台电脑上,放入tomcat中运行找不到路径,报错404.重新创建一个servlet运行就可以正常访问到. 2.但上传的文件过大时上传文件会报404错误 把<prope ...

  6. 你说一下Redis为什么快吧,怎么实现高可用,还有持久化怎么做的?

    前言 作为Java程序员,在面试过程中,缓存相关的问题是躲不掉的,肯定会问,例如缓存一致性问题,缓存雪崩.击穿.穿透等.说到缓存,那肯定少不了Redis,我在面试的时候也是被问了很多关于Redis相关 ...

  7. 如何理解SQL的可重复读和幻读之间的区别?

    从本源来理解比较容易理解,如果只是描述概念和定义,容易让人云里雾里找不到方向.正好这两天在浏览mysql的文档,我可以简单在这里总结一下,帮助其他还没有理解的朋友,如果有错误也麻烦帮忙指正. 先讲一点 ...

  8. IO输入和输出

    编程语言的I/O类库中常用使用流这个抽象概念,它代表任何有能力产出数据的数据源对象或者是有能力接收数据的接受端对象."流"屏蔽了实际的I/O设备中处理数据的细节. JAVA类库中的 ...

  9. 通过python的socket库实现简易即时通讯小程序

    前言 最近学习了一下有关tcp协议和socket有关的知识,看到许多socket实战都喜欢教如何做一个聊天程序,于是想着试试能不能不看教程自己写一个.当然我没太多时间做一个像qq一样的ui界面,所以做 ...

  10. ROS开源小车TurtleBot3详情介绍(Burger)

    您为什么要选择ROS开源智能小车 ROS(RobotOperating System,机器人操作系统)是目前世界上更主流更多人使用的的机器人开源操作系统.它可以提供操作系统应有的服务,包括硬件抽象,底 ...