Luogu P2458 [SDOI2006]保安站岗【树形Dp】
2018-07-25 08:10
253 查看
题目描述
五一来临,某地下超市为了便于疏通和指挥密集的人员和车辆,以免造成超市内的混乱和拥挤,准备临时从外单位调用部分保安来维持交通秩序。
已知整个地下超市的所有通道呈一棵树的形状;某些通道之间可以互相望见。总经理要求所有通道的每个端点(树的顶点)都要有人全天候看守,在不同的通道端点安排保安所需的费用不同。
一个保安一旦站在某个通道的其中一个端点,那么他除了能看守住他所站的那个端点,也能看到这个通道的另一个端点,所以一个保安可能同时能看守住多个端点(树的结点),因此没有必要在每个通道的端点都安排保安。
编程任务:
请你帮助超市经理策划安排,在能看守全部通道端点的前提下,使得花费的经费最少。
输入输出格式
输入格式:
第1行 n,表示树中结点的数目。
第2行至第n+1行,每行描述每个通道端点的信息,依次为:该结点标号i(0<i<=n),在该结点安置保安所需的经费k(<=10000),该边的儿子数m,接下来m个数,分别是这个节点的m个儿子的标号r1,r2,...,rm。
对于一个n(0 < n <= 1500)个结点的树,结点标号在1到n之间,且标号不重复。
输出格式:
最少的经费。
如右图的输入数据示例
输出数据示例:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 5 using namespace std; 6 typedef long long ll; 7 8 int n,tot; 9 int head[2000],f[2000][5]; 10 11 struct node{ 12 int to,next; 13 }edge[4000]; 14 15 void add(int x,int y) 16 { 17 edge[++tot].to=y; 18 edge[tot].next=head[x]; 19 head[x]=tot; 20 } 21 22 void TreeDP(int x,int fa) 23 { 24 int cha=0x7f7f7f7f,cnt=0; 25 for(int i=head[x];i;i=edge[i].next) 26 { 27 int y=edge[i].to; 28 if(y==fa) continue; 29 TreeDP(y,x); 30 f[x][0]+=min(f[y][1],f[y][2]); 31 f[x][1]+=min(min(f[y][0],f[y][1]),f[y][2]); 32 /*if(f[y][1]<f[y][2]) f[x][2]+=f[y][1],flag=true; 33 else 34 { 35 if(flag) f[x][2]+=f[y][2]; 36 else 37 if(fabs(f[y][1]-f[y][2])<min_cha) 38 min_cha=fabs(f[y][1]-f[y][2]),jian=f[y][2],jia=f[y][1],f[x][2]+=f[y][2]; 39 else f[x][2]+=f[y][2]; 40 } 41 } 42 if(!flag) f[x][2]=f[x][2]-jian+jia;*///我写的初始版本,但是太丑了QAQ 43 if(f[y][1]<f[y][2]) cnt++; 44 else cha=min(cha,f[y][1]-f[y][2]); 45 f[x][2]+=min(f[y][1],f[y][2]); 46 } 47 if(cnt==0) f[x][2]+=cha; 48 } 49 50 int main() 51 { 52 scanf("%d",&n); 53 for(int i=1;i<=n;i++) 54 { 55 int p,k,u,m; 56 scanf("%d%d%d",&p,&k,&m); 57 f[p][1]=k;//注意这句!我被坑了好久!不是f[i][1]=k! 58 for(int i=1;i<=m;i++) 59 { 60 scanf("%d",&u); 61 add(p,u);//由于没有暗示本题有明确的父子关系,所以还是连双向边的好 62 add(u,p); 63 } 64 } 65 TreeDP(1,0);//dfs传两个参数,一个是当前节点,一个是当前节点的父节点,是个好习惯,可以在后来的判断中防止死循环以及奇怪的MLE! 66 printf("%d",min(f[1][1],f[1][2])); 67 return 0; 68 }View Code
小结:本题是进阶的树形dp,只要把情况仔细梳理认真分类讨论就ok了!
相关文章推荐
- 【洛谷2458】【SDOI2006】保安站岗(树形DP)
- SDOI 2006 - 保安站岗
- [SDOI2006]保安站岗 树dp
- [SDOI2006]保安站岗
- [SDOI2006]保安站岗
- [luogu 2458][SDOI2006]保安站岗
- BZOJ1864 [Zjoi2006]三色二叉树 树形DP
- BZOJ5333 [Sdoi2018]荣誉称号 【差分 + 树形dp】
- BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】
- BZOJ 1864: [Zjoi2006]三色二叉树( 树形dp )
- [BZOJ2286][Sdoi2011]消耗战(虚树+lca+树形dp)
- [BZOJ3124][Sdoi2013]直径(树形dp)
- bzoj1495 [NOI2006] 网络收费 树形DP
- BZOJ1864[ZJOI2006]三色二叉树[树形DP]
- BZOJ_1495_[NOI2006]网络收费_树形DP
- bzoj1495 [NOI2006]网络收费(状压/暴力+树形dp)
- 2286: [Sdoi2011消耗战|树形DP|虚树
- BZOJ2286 [Sdoi2011]消耗战 (虚树 + 树形DP)
- bzoj3124 [Sdoi2013]直径 直径+树形dp
- 【BZOJ2286】【SDOI2011】消耗战 LCA单调性(构建虚树)+树形DP