【题解】保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006]

传送门:皇宫看守\([LOJ10157]\) 保安站岗 \([P2458]\) \([SDOI2006]\)

【题目描述】

给你一棵树,要求树上每个点都要有人看守,在不同的点安排守卫所需 \(Monney\) 不同。
守卫站在某个端点上时,他除了能看守住他所站的那个点,也能看守通过一条边与之相连的另一个端点,因此一个守卫可能同时能看守住多个点,因此没有必要在每个端点上都安排守卫。

要求在能够看守住所有点的前提下,使得花费的 \(Monney\) 最少。

【输入】

第 \(1\) 行一个整数 \(n\),表示树中节点的数目。
接下来 \(n\) 行,每行描述每个结点的信息,依次为:该结点标号 \(i\),在该结点安置保安所需的经费 \(k_i\),该边的儿子数 \(m\),接下来 \(m\) 个数,分别是这个节点的 \(m\) 个儿子的标号 \(r_1,r_2,r_3...r_m\)。

对于一个 \(n\) 个结点的树,其结点标号在 \(1\) 到 \(n\) 之间,且标号不重复。

【输出】

输出一行一个整数,表示花费的最少 \(Monney\) 。

【样例】

样例输入:
6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0样例输出:
25

【数据范围】

\(100\%\) \(1 \leqslant N \leqslant 1500,1 \leqslant k_i \leqslant 10000\)


【分析】

一道经典的树形 \(dp\) 。

用 \(dp[i][0]\) 表示:自己不是守卫,父亲不是守卫,儿子是守卫

用 \(dp[i][1]\) 表示:自己是守卫,父亲不知道,儿子不知道

用 \(dp[i][2]\) 表示:自己不是守卫,父亲是守卫,儿子不知道

在树上 \(dfs\) 遍历。

每到达一个 \(x\),先对其进行初始化:\(dp[x][1]=w[x],dp[x][2]=dp[x][0]=0\)(其中 \(w[x]\) 为在 \(x\) 这个位置放守卫所需 \(Monney\))。

然后遍历它的若干个儿子结点,更新三个 \(dp[x][?]\):

\((1).\) \(dp[x][1]\):\(x\) 是守卫,\(x\) 的父亲不知道,\(x\) 的儿子 \(to\) 不知道
对于 \(to\) 来说,\(to\) 的父亲一定是守卫,所以 \(dp[to][0]\) 就不统计了,于是有:\(dp[x][1]=\sum_{to \in son[x]} min(dp[to][1],dp[to][2])\)

\((2).\) \(dp[x][2]\):\(x\) 不是守卫,\(x\) 的父亲是守卫,\(x\) 的儿子 \(to\) 不知道

对于 \(to\) 来说,\(to\) 的父亲不可能是守卫,于是有:\(dp[x][2]=\sum_{to \in son[x]} min(dp[to][1],dp[to][0])\)

\((3).\) \(dp[x][0]\):\(x\) 不是守卫,\(x\) 的父亲不是守卫,\(x\) 的儿子 \(to\) 是守卫

这是最复杂的情况,需要在 \(son[x]\) 选出一个 \(dp[to][1]\),而其他的儿子则是 \(min(dp[to][1],dp[to][0])\)。

可以对所有儿子维护一个 \(dp[to][1]\) 与 \(min(dp[to][1],dp[to][0])\) 的差值 \(dd\),然后在最后把最小的差值 \(dd_{min}\) 加到 \(dp[to][0]\) 上即可。

于是 \(dd={(dp[r][1]-min(dp[r][0],dp[to][1]))}^{r \in son[x]}_{min},\) \(dp[to][0]=\sum_{to \in son[x]} min(dp[r][1],dp[r][0])+dd\)

【Code】

#include<algorithm>
#include<cstring>
#include<cstdio>
#define R register int
using namespace std;
struct QAQ{int to,next;}a[1505];
int m,pan[1505],n,t,w[1505],dp[1505][3],head[1505];
inline void add(int x,int y){a[++t].to=y,a[t].next=head[x],head[x]=t;}
//dp[i][0] 自己不是守卫,父亲不是守卫,儿子是守卫
//dp[i][1] 自己是守卫,  父亲不知道,  儿子不知道
//dp[i][2] 自己不是守卫,父亲是守卫,  儿子不知道
inline void dfs(int x){R i,to,dd=0xfffffff;dp[x][1]=w[x];dp[x][2]=0;dp[x][0]=0;for(i=head[x];i;i=a[i].next){dfs(to=a[i].to);dd=min(dd,dp[to][1]-min(dp[to][0],dp[to][1]));//维护最小的差值 dp[x][0]+=min(dp[to][0],dp[to][1]);//若x守卫是儿子dp[x][0],找到花费最小的dd 加上其他的儿子:min(1.孙子dp[to][0]。2.自己dp[to][1]。) dp[x][1]+=min(dp[to][1],dp[to][2]);
//若x有守卫dp[x][1],加上儿子:min(1.父亲dp[to][2]。2.自己dp[to][1]。) dp[x][2]+=min(dp[to][0],dp[to][1]);
//若守卫是父亲dp[x][2],加上儿子:min(1.孙子dp[to][0]。2.自己dp[to][1]。) }dp[x][0]+=dd;
}
int main(){memset(dp,127,sizeof(dp));scanf("%d",&n);R i,j,a,k,r;for(i=1;i<=n;i++){scanf("%d%d%d",&a,&k,&m);w[a]=k;for(j=1;j<=m;j++)scanf("%d",&r),pan[r]=1,add(a,r);}for(i=1;i<=n;i++)if(!pan[i]){dfs(i);printf("%d",min(dp[i][1],dp[i][0]));return 0;}
}

转载于:https://www.cnblogs.com/Xing-Ling/p/11179420.html

【题解】保安站岗[P2458]皇宫看守[LOJ10157][SDOI2006]相关推荐

  1. AcWing 1077. 皇宫看守(树形DP + 状态机DP)

    AcWing 1077. 皇宫看守(树形DP + 状态机DP) 一.问题 二.分析 1.思路分析 2.状态表示 3.状态转移 4.循环设计 5.初末状态 三.代码 一.问题 二.分析 1.思路分析 在 ...

  2. Acwing 1077.皇宫看守

    Acwing 1077.皇宫看守 题目 输入格式 输出格式 数据范围 输入样例 输出样例 样例解释 分析 详细代码 这是我第一篇博客,如有侵权或者不足的地方,我将予以修改,并改正 题目 太平王世子事件 ...

  3. Acwing 1077. 皇宫看守

    参考题目:Acwing 1077. 皇宫看守 题意 给定一个树,求覆盖所有点的最少花费. 算法:树形DP 时间复杂度: O ( n ) O(n) O(n) (每个点只被搜索一次) f 数组含义: f[ ...

  4. AcWing1077. 皇宫看守(树形DP)题解

    题目传送门 题目描述 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状,某些宫殿间可以互相望见. 大内保卫森严,三步一岗,五步一哨,每个宫殿 ...

  5. [SDOI2006] 保安站岗

    题目链接 第一遍不知道为什么就爆零了-- 第二遍改了一下策略,思路没变,结果不知道为什么就 A 了??? 树形 DP 经典问题:选择最少点以覆盖树上所有点(边). 对于本题,设 dp[i][0/1][ ...

  6. [SDOI2006]保安站岗 树dp

    要记录三种状态: 1.被子节点覆盖 2.等待父节点覆盖 3.建立覆盖节点 然后转移就好了,有一点麻烦的就是被子节点覆盖,需要保证至少有一个子节点建立 注:检查变量名与实际含义. 码: #include ...

  7. LOJ10157——皇宫看守(树形DP)

    传送门:QAQQAQ 题意:在一个树上放置守卫,使每一个节点都至少有相邻一节点放置守卫,使最终经费最少 思路:树形DP 首先会想到没有上司的舞会,0表示不放守卫,1表示放守卫,但考虑到对于当前点不放守 ...

  8. loj10157. 「一本通 5.2 例 5」皇宫看守

    思路: 例四是覆盖全部边,dp两个状态,例五是覆盖全部点,dp三个状态. #include<cstdio> #include<iostream> #include<cst ...

  9. CIA1 皇宫看守(树形dp)

    问题描述:太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候 ...

  10. 皇宫看守(guard)

    [问题描述] 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:有边直接相连的宫殿可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都 ...

最新文章

  1. C#隐藏手机号中间四位为*
  2. Windows 2012 R2 中 AD DS 部署
  3. php中的unbuffered_row,php – 加载数据infile和unbuffered查询错误
  4. 太吾绘卷存档修改2020_太吾绘卷/神级初始存档
  5. Jenkins 关闭和重启实现方式.
  6. Java中遭遇NaN
  7. 函数或变量 rtenslearn_c 无法识别_深度学习的数学-卷积神经网络的结构和变量关系...
  8. Android UI系列-----Dialog对话框
  9. 夏昕.深入浅出Hibernate中的第一个例子体会.
  10. jbpm5.4 mysql_5.BDF2-JBPM4
  11. python小课风变编程_风变编程Python小课最近很火,大家学完感受如何?
  12. 第五节:蜂鸣器的驱动程序
  13. 工作流与BPM的区别
  14. 贝壳找房app使用Glide替换Picasso
  15. sqlilabs-mysql数据库注入靶场-page2
  16. 见过贪婪的,没见过这么贪婪的
  17. 红包 java_利用java发红包(1)之红包分配方法
  18. 6.堆(动态内存 heap)的初始化和使用
  19. plsql和navicate有什么区别_navicat的使用(测试库和正式库同步)以及用plsql改表字段属性...
  20. matlab整流桥长什么样,matlab器件整流桥仿真.docx

热门文章

  1. 鸡兔同笼(一道明显的体现cin和cout运行较慢的特点)
  2. git指定版本openwrt源码_关于Github Action自动编译Lean_Openwrt的配置修改问题
  3. len函数实例python_Python通过len函数返回对象长度
  4. 英文文本处理 c github_真香警告!有了这个搜索大法,GitHub可以玩到飞起来!
  5. 小牛uqi几个版本区别_川崎ZX25R便宜版本长这样?
  6. 【UVA11168】Airport(凸包+点到直线距离(一般式))
  7. 平面圆域分割(欧拉公式)+例题
  8. linux 进程 cpu 100,清理linux中占用CPU 100%的病毒
  9. android+p+华为手机,Android P六大特性曝光支持刘海屏_华为 P20_手机新闻-中关村在线...
  10. 华为平板 鸿蒙2.0,华为鸿蒙2.0支持型号有哪些