luoguP2016 战略游戏

题目描述

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;
}

原文地址:https://www.cnblogs.com/akura/p/10913924.html

时间: 2024-08-30 06:47:59

luoguP2016 战略游戏的相关文章

[luoguP2016] 战略游戏(DP)

传送门 f[i][0]表示不选当前节点,当前节点的所有儿子节点都选f[i][1]表示选当前节点,儿子节点可选可不选 #include <cstdio> #include <cstring> #include <iostream> #define N 1501 #define min(x, y) ((x) < (y) ? (x) : (y)) int n, cnt; int head[N], to[N << 1], next[N << 1],

Facebook开源游戏平台ELF: 一个用于实时战略游戏研究的轻量级平台

ELF是一个用于游戏研究的应用广泛的(Extensive).轻量级的(Lightweight).灵活的(Flexible)平台,特别适用于实时战略(RTS)游戏.在C++方面,ELF采用C++线程来并发运行多个游戏.在Python方面,ELF可以一次性返回一批游戏状态,使其对现代RL(强化学习)非常友好.另一方面,在其他平台(例如OpenAI Gym)中,一个Python接口只能包含一个游戏实例.这使得游戏的并发运行有点复杂,而这又是许多现代强化学习算法的要求. 对于RTS游戏的研究,ELF配备

战略游戏

题意/Description: Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路.注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到.  请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵. 读入/Input:    输入文件中数据表示一棵树,描述如下: 第一行 N,表示树中结点的数目. 第二行至第N+1行,每行描述每个

bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分

[BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和别人打仗了. 在打仗之前,幽香现在面临一个非常基本的管理问题需要解决. 整个地图是一个树结构,一共有n块空地,这些空地被n-1条带权边连接起来,使得每两个点之间有一条唯一的路径将它们连接起来.在游戏中,幽香可能在空地上增加或者减少一些军

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

[BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到那个子树的根节点上一定最优 那么,现在是动态修改 考虑动态点分治 在每个点上维护子树的兵的总数 子树到上一层父亲节点 向上走产生的贡献的总和 以及接收到子节点的贡献的总和 那么,就可以计算当前点产生的贡献 于是,从分治树根开始向下贪心即可 #include<iostream> #include&l

bzoj 5329 [SDOI2018] 战略游戏

bzoj 5329 [SDOI2018] 战略游戏 Link Solution 很容易想到虚树 然后发现是一个图... 现学圆方树,套上去,做完了(模板题?) 就是直接上广义圆方树先把这玩意转换成一棵树,然后对当前询问建立虚树,断掉虚树里任何一个点都合法(包括不出现的点,指那些在某个点和其虚树上父亲之间的点),统计一下即可 Code // Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib>

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

[SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中的圆点个数减去\(S\).问题变成了怎样求这样的连通块中的圆点个数,直接给结论吧:先搞出树的dfs序,把询问的点按dfs序从小到大排一遍序,每次把答案加上第\(i\)和第\(i + 1\)个点之间的圆点个数,但是不算lca,再加上第\(1\)个和第\(S\)个点之间的圆点个数,然后除以二就得到了这个

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

通过两道简单的例题,我们来重新认识树形DP. 战略游戏(luoguP1026) Description Bob喜欢玩电脑游戏,特别是战略游戏.但是他经常无法找到快速玩过游戏的办法.现在他有个问题.他要建立一个古城堡,城堡中的路形成一棵树.他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路.注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到. 请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵. Input Format 输入文件中数据表示一棵树,描述如下

[SDOI2018]战略游戏

题目描述 省选临近,放飞自我的小Q无心刷题,于是怂恿小C和他一起颓废,玩起了一款战略游戏. 这款战略游戏的地图由n个城市以及m条连接这些城市的双向道路构成,并且从任意一个城市出发总能沿着道路走到 任意其他城市.现在小C已经占领了其中至少两个城市,小Q可以摧毁一个小C没占领的城市,同时摧毁所有连接这 个城市的道路.只要在摧毁这个城市之后能够找到某两个小C占领的城市u和v,使得从u出发沿着道路无论如何都不 能走到v,那么小Q就能赢下这一局游戏. 小Q和小C一共进行了q局游戏,每一局游戏会给出小C占领