Luogu P2458 [SDOI2006]保安站岗【树形Dp】
题目描述
五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序。
已知整个地下超市的所有通道呈一棵树的形状;某些通道之间可以互相望见。总经理要求所有通道的每个端点(树的顶点)都要有人全天候看守,在不同的通道端点安排保安所需的费用不同。
一个保安一旦站在某个通道的其中一个端点,那么他除了能看守住他所站的那个端点,也能看到这个通道的另一个端点,所以一个保安可能同时能看守住多个端点(树的结点),因此没有必要在每个通道的端点都安排保安。
编程任务:
请你帮助超市经理策划安排,在能看守全部通道端点的前提下,使得花费的经费最少。
输入输出格式
输入格式:
第1行 n,表示树中结点的数目。
第2行至第n+1行,每行描述每个通道端点的信息,依次为:该结点标号i(0<i<=n),在该结点安置保安所需的经费k(<=10000),该边的儿子数m,接下来m个数,分别是这个节点的m个儿子的标号r1,r2,...,rm。
对于一个n(0 < n <= 1500)个结点的树,结点标号在1到n之间,且标号不重复。
输出格式:
最少的经费。
如右图的输入数据示例
输出数据示例:
输入输出样例
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
说明
样例说明:在结点2,3,4安置3个保安能看守所有的6个结点,需要的经费最小:25
Sol
背景和战略游戏是一样的,但是战略游戏求的是树上的最小点覆盖,可以用树形dp,也可以用二分图的一个定理。也就是说放置士兵的个数。
但本题求的是最小权值,而且稍有不同的是,本题望的是点,战略游戏望边。
但是不管怎么样,它还是在树上啊!树形dp能搞过。
我们冷静分析可知:一个节点有三种情况
0:当前没有被看,将来会被父节点看
( 由于树形dp是从下往上传递信息的 )
1:当前被看,且此处有保安
2:当前被看,但 是因为儿子处有保安。
则状态显然: f[x][0/1/2] 表示以x为根的子树的不同情况下所需的最小权值。
对于情况0,f [x] [0] + =sigma -> min( f[y][2],f[y][1] ) 只要儿子节点被看就好。
对于情况1,f [x] [1] +=sigma -> min ( f[y][2],f[y][1],f[y][0] ) +val[x]
对于情况2,f [x] [2] +=sigma -> min ( f[y][2],f[y][1] ) 但当前节点是被看的,则必须满足有一个儿子的f[y][1]小于f[y][2],但当没有这个条件满足时,也需要一个f[y][1],我们可以求出所有儿子的这两个值之差的最小值,取一个f[y][1]。
最后结果即为 max ( f[root][1],f[root][2] )
注:这道题默认1是根节点,但题面(貌似)没有给出明确的暗示,所有最好还是养成找根节点的习惯。
code
#include<cstdio>
#include<algorithm>
#include<cmath> using namespace std;
typedef long long ll; int n,tot;
int head[],f[][]; struct node{
int to,next;
}edge[]; void add(int x,int y)
{
edge[++tot].to=y;
edge[tot].next=head[x];
head[x]=tot;
} void TreeDP(int x,int fa)
{
int cha=0x7f7f7f7f,cnt=;
for(int i=head[x];i;i=edge[i].next)
{
int y=edge[i].to;
if(y==fa) continue;
TreeDP(y,x);
f[x][]+=min(f[y][],f[y][]);
f[x][]+=min(min(f[y][],f[y][]),f[y][]);
/*if(f[y][1]<f[y][2]) f[x][2]+=f[y][1],flag=true;
else
{
if(flag) f[x][2]+=f[y][2];
else
if(fabs(f[y][1]-f[y][2])<min_cha)
min_cha=fabs(f[y][1]-f[y][2]),jian=f[y][2],jia=f[y][1],f[x][2]+=f[y][2];
else f[x][2]+=f[y][2];
}
}
if(!flag) f[x][2]=f[x][2]-jian+jia;*///我写的初始版本,但是太丑了QAQ
if(f[y][]<f[y][]) cnt++;
else cha=min(cha,f[y][]-f[y][]);
f[x][]+=min(f[y][],f[y][]);
}
if(cnt==) f[x][]+=cha;
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int p,k,u,m;
scanf("%d%d%d",&p,&k,&m);
f[p][]=k;//注意这句!我被坑了好久!不是f[i][1]=k!
for(int i=;i<=m;i++)
{
scanf("%d",&u);
add(p,u);//由于没有暗示本题有明确的父子关系,所以还是连双向边的好
add(u,p);
}
}
TreeDP(,);//dfs传两个参数,一个是当前节点,一个是当前节点的父节点,是个好习惯,可以在后来的判断中防止死循环以及奇怪的MLE!
printf("%d",min(f[][],f[][]));
return ;
}
小结:本题是进阶的树形dp,只要把情况仔细梳理认真分类讨论就ok了!
Luogu P2458 [SDOI2006]保安站岗【树形Dp】的更多相关文章
- Luogu P2458 [SDOI2006]保安站岗(树形dp)
P2458 [SDOI2006]保安站岗 题意 题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下 ...
- P2458 [SDOI2006]保安站岗[树形dp]
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- [Luogu][P2458] [SDOI2006]保安站岗
题目链接 看起来似乎跟最小点覆盖有点像.但区别在于: 最小点覆盖要求所有边在其中,而本题要求所有点在其中. 即:一个点不选时,它的儿子不一定需要全选. 画图理解: 对于这样一幅图,本题中可以这样选择: ...
- C++ 洛谷 P2458 [SDOI2006]保安站岗 from_树形DP
P2458 [SDOI2006]保安站岗 没学树形DP的,看一下. 题目大意:一棵树有N个节点,现在需要将所有节点都看守住,如果我们选择了节点i,那么节点i本身,节点i的父亲和儿子都会被看守住. 每个 ...
- [luogu 2458][SDOI2006]保安站岗
题目描述 五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序. 已知整个地下超市的所有通道呈一棵树的形状:某些通道之间可以互 ...
- 洛谷 P2458 [SDOI2006]保安站岗
题目传送门 解题思路: 树形DP 可知一个点被控制有且仅有一下三种情况: 1.被父亲节点上的保安控制 2.被儿子节点上的保安控制 3.被当前节点上的保安控制 我们设dp[0/1/2][u]表示u节点所 ...
- [SDOI2006] 保安站岗
题目链接 第一遍不知道为什么就爆零了…… 第二遍改了一下策略,思路没变,结果不知道为什么就 A 了??? 树形 DP 经典问题:选择最少点以覆盖树上所有点(边). 对于本题,设 dp[i][0/1][ ...
- 【Luogu】P3174毛毛虫(树形DP)
题目链接 树形DP水题,设f[x][0]是以x为根的子树,内部只有半条链(就是链的两个端点一个在子树里,一个不在子树里)的最大值,f[x][1]是以x为根的子树,内部有一条完整的链(选两个内部的子树作 ...
- Luogu P1273 有限电视网【树形Dp/树形背包】
题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从 ...
随机推荐
- 洛谷——P1047 校门外的树
P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...
- 2017CodeM初赛B场
A.合并字符串价值(loj6174) 分析: 普通暴力:枚举两个分界线,那么ans=Σmin(Al(c)+Bl(c),Ar(c)+Br(c)),这样是O(n^2),会TLE 考虑枚举a的分界线,b的答 ...
- Spring MVC的Hello World例子
以下内容引用自http://wiki.jikexueyuan.com/project/spring/mvc-framework/spring-mvc-hello-world-example.html: ...
- 基于gulp编写的一个简单实用的前端开发环境
自从Node.js出现以来,基于其的前端开发的工具框架也越来越多了,从Grunt到Gulp再到现在很火的WebPack,所有的这些新的东西的出现都极大的解放了我们在前端领域的开发,作为一个在前端领域里 ...
- Spring @Value用法
Spring 通过注解获取*.porperties文件的内容,除了xml配置外,还可以通过@value方式来获取. 使用方式必须在当前类使用@Component,xml文件内配置的是通过pakage扫 ...
- sgu208:Toral Tickets(Pólya定理)
题意简述:给你N和M,对于一个N∗M的单面方格纸你能够对它的每 个个格子黑白染色.然后把方格纸的长边卷起来,卷成一个圆柱体,然后再把 两个短边形成的圆也接起来.形成一个游泳圈的形状(我们染的色仅仅在游 ...
- There is no PasswordEncoder mapped for the id "null"
There is no PasswordEncoder mapped for the id "null" 学习了:https://blog.csdn.net/dream_an/ar ...
- DICOM:再次剖析fo-dicom中DicomService的自己定义事件绑定
题记: 趁着<从0到1>大火的热潮,最近又一次翻阅了一遍<从一到无穷大>(这样是不是感觉整个非负数轴就圆满了^_^). 尽管作为科普类书籍.可是里面的内容还是比較深奥,幸亏有作 ...
- Android进程绝杀技--forceStop(转)
一.概述 1.1 引言 话说Android开源系统拥有着App不计其数,百家争鸣,都想在这“大争之世”寻得系统存活的一席之地.然则系统资源有限,如若都割据为王,再强劲的CPU也会忙不过来,再庞大的内存 ...
- update语句执行卡死现象原因及解决方案
https://blog.csdn.net/wpz0713/article/details/51499654 原因分析: 可能在PLSQL Developer执行update时没有commit,ora ...