【题目描述】
一个重要的基地被分成了 n 个连通的区域 , 出于某种原因 , 这个基地以某一个区域为核
心,呈一树形分布。
在每个区域里安排警卫的费用是不同的,而每个区域的警卫都可以望见其相邻的区域 。
如果一个区域有警卫或是被相邻区域的警卫望见 , 那它就是安全的 , 你的任务是 : 在确保所
有的区域安全的状态下,使总费用最小。
【输入格式】
第一行 n ,表示树中结点的数目。
接下来 n 行,每行依次是:区域的编号;在此安排警卫的费用;它的子结点的个数 m ,
然后往后 m 个数,为它的子结点编号。
【输出格式】
一行一个数,为最小费用。

【输入样例】
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

 #include <cstdlib>
#include <fstream>
#include <cstring>
#include <iostream> using namespace std; ifstream fin("security.in");
ofstream fout("security.out"); int cnt_node=;//点的个数
bool fuqin[]={false};//判断是否有父节点 int head[]={},cnt=;
struct liansi{
int to;
int nxt;
};
liansi lian_son[]={};//链式前向星 int paying[]={};//每个警卫处要安排警察的费用
int p_state[][]={}; //状态 void add(int a,int b);//链式前向星
void plan(int size,int state); void add(int a,int b){
lian_son[++cnt].to=b;
lian_son[cnt].nxt=head[a];
head[a]=cnt;
return;
} void plan(int size,int state){
if(head[size]==-){//当前节点为数最底部
p_state[size][state]=;//如果状态为父亲看守 花费为0
if(state==){
p_state[size][]=paying[size]; //状态为自己看守 ,花费为自己安排警卫所付的钱
}
return;
} if(state==){//当前节点自己安排警卫
int sum=;
for(int hao=head[size];hao!=-;hao=lian_son[hao].nxt){
int minn=0x7fffff;
int son=lian_son[hao].to; if(p_state[son][]<)plan(son,);//它的儿子可以让父亲看守
minn=min(minn,p_state[son][]);//打擂 求最小 if(p_state[son][]<)plan(son,); //可以自己看守(为便利子孙)
minn=min(minn,p_state[son][]);//打擂 求最小 if(head[son]!=-){//它的儿子也可以让自己儿子看守 这里是说它的儿子有儿子
if(p_state[son][]<)plan(son,);
minn=min(minn,p_state[son][]); //打擂 求最小
}
sum+=minn;//加上所以儿子所用最小值
}
p_state[size][]=sum+paying[size];//再加上自己的安排警卫的钱,为当前节点安排警卫所花费最小金额
} if(state==){//如果让父亲看守
int sum=;
for(int hao=head[size];hao!=-;hao=lian_son[hao].nxt){
int minn=0x7fffff;
int son=lian_son[hao].to; if(p_state[son][]<)plan(son,);//当前节点的儿子要么自己看守
minn=min(minn,p_state[son][]); if(head[son]!=-){
if(p_state[son][]<)plan(son,);//要么有儿子就让儿子看守
minn=min(minn,p_state[son][]);
}
sum+=minn;
}
p_state[size][]=sum;
} if(state==){//表示当前节点由某一儿子看守
int Min=0x7fffff;
for(int hao=head[size];hao!=-;hao=lian_son[hao].nxt){
int sum=, meijv=lian_son[hao].to; //枚举看守儿子节点 for(int hao2=head[size];hao2!=-;hao2=lian_son[hao2].nxt){
int minn=0x7fffff, son=lian_son[hao2].to; if(son!=meijv){//计算非枚举子节点所要花费最小值 if(p_state[son][]<)plan(son,);
minn=min(minn,p_state[son][]);
if(head[son]!=-){
if(p_state[son][]<)plan(son,);
minn=min(minn,p_state[son][]);
}
sum+=minn;
}
}
if(p_state[meijv][]<)plan(meijv,);//计算枚举看守儿子看守的最小值
Min=min(Min,sum+p_state[meijv][]);
}
p_state[size][]=Min;
} return;
} int main(){
fin>>cnt_node; memset(head,-,sizeof(head)); for(int x=;x<=cnt_node;x++){
int s1ze=,paid=,cnt_son=;
fin>>s1ze>>paid>>cnt_son;//输入编号花费与子节点个数
paying[s1ze]=paid;
for(int y=;y<=cnt_son;y++){
int son=;
fin>>son;
fuqin[son]=true;//表示此编号有父节点
add(s1ze,son); //用链式前向星将父节点与子节点连接起来
}
} int gen=;//根
for(int i=;i<=cnt_node;i++){
if(fuqin[i]==false){//如果一个点没有父节点
gen=i;//那么它就是根
break;
}
} memset(p_state,-,sizeof(p_state));//将所有状态默认为-1 plan(gen,); //表示它自己放警卫 自己看守
plan(gen,);//表示让它儿子放警卫 让儿子看守
int ans=min(p_state[gen][],p_state[gen][]);//比较哪种费用最低
cout<<ans;
fout<<ans;
return ;
} /*
核心思路:
划分阶段:
0.由父亲看守,那么它的儿子要么自己看守,要么让它儿子看守
1.有由自己看守,那么自己的儿子可以不看守,也可以看守便利子孙
2.由某一个儿子看守,其它儿子照样可以选择自己看守,还是由自己的儿子看守
*/

【题解】警位安排( 树形 DP)的更多相关文章

  1. codeforces766E Mahmoud and a xor trip(按位统计+树形DP)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  2. 3月28日考试 题解(二分答案+树形DP+数学(高精))

    前言:考试挂了很多分,难受…… --------------------- T1:防御 题意简述:给一条长度为$n$的序列,第$i$个数的值为$a[i]$.现让你将序列分成$m$段,且让和最小的一段尽 ...

  3. 【BZOJ1864】[Zjoi2006]三色二叉树 树形DP

    1864: [Zjoi2006]三色二叉树 Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最 ...

  4. POJ1947 - Rebuilding Roads(树形DP)

    题目大意 给定一棵n个结点的树,问最少需要删除多少条边使得某棵子树的结点个数为p 题解 很经典的树形DP~~~直接上方程吧 dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v] ...

  5. hdu_Anniversary party_(树形DP入门题)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:有N个人,N-1个人有自己的上司,每个人有一个快乐值,如果这个人参加了聚会,那么这个人的直 ...

  6. bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]

    4871: [Shoi2017]摧毁"树状图" 题意:一颗无向树,选两条边不重复的路径,删去选择的点和路径剩下一些cc,求最多cc数. update 5.1 : 刚刚发现bzoj上 ...

  7. hdu5293 Tree chain problem 树形dp+线段树

    题目:pid=5293">http://acm.hdu.edu.cn/showproblem.php?pid=5293 在一棵树中,给出若干条链和链的权值.求选取不相交的链使得权值和最 ...

  8. hdu3586 Information Disturbing 【树形dp】

    题目链接 hdu3586 题解 二分 + 简单的树形dp 我正有练一下dp的必要了 #include<iostream> #include<cstdio> #include&l ...

  9. Hackrank Kingdom Division 树形DP

    题目链接:传送门 题意: 给你一棵树,n个点 每个点可以染成红色和蓝色 但是红色的点与其相邻的点中必须有红色节点,蓝色也是 问你有多少种染色的方案 题解: 树形dp 先转化为有根树,取1为根 设定dp ...

随机推荐

  1. 学 Android 是一种什么样的体验?

    转眼间 2016 年的电量已不足 20%,不禁感慨 How Time Flies!不知不觉 Android 移动开发已经走过了八年的光阴,在这八年的时间中,Android 开发从最初的简单调用系统 A ...

  2. Activity启动过程简要介绍

    无论是通过点击应用程序图标来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都要借助于应用程序框架层的ActivityManagerSe ...

  3. c++清除输入缓冲区之 sync() vs ignore()

    最近在写程序的时候总是不注意输入缓冲区内是否还有东西,导致出现了一些异常,调试了半天.所以来上一贴,学习注意,引以为戒! http://blog.chinaunix.net/uid-21254310- ...

  4. eclipse + maven + jboss 遇到ClassNotFoundException

    在使用eclipse + maven + jboss开发过程中,碰到ClassNotFoundException, 原因应该是deployed包中未包含maven的依赖jar. 可以通过如下方法把依赖 ...

  5. IPv6被拒如何破?-b

    APP在美国的IPv6-Only网络环境下测试不通过. 网上各种方法都试了,什么NSURLConnection, Reachability,试完还是拼人品,快要跪了 小伙伴们开始质疑这种测试方法了. ...

  6. 《深入剖析Tomcat》阅读(二)

    Tomcat是基于Sun公司标准的开源Servlet容器. Servlet是什么? Servlet(Server Applet),全称Java Servlet,未有中文译文.是用Java编写的服务器端 ...

  7. 一个短路求值引起的一个小bug

    今天在写一个判断字符串是否回文时因为短路求值问题导致了一个bug,记录如下: 代码如下 bool isPal(char str[],int len) { int begin=0; int end=le ...

  8. codeforces D. Pashmak and Parmida's problem

    http://codeforces.com/contest/459/problem/D 题意:给你n个数,然后统计多少组(i,j)使得f(1,i,ai)>f(j,n,aj); 思路:先从左往右统 ...

  9. tomcat修改默认web目录

    有两种方法: 1.tomcat目录下的conf文件夹, server.xml <Context path="" docBase="d:\myapp" de ...

  10. 余弦距离、欧氏距离和杰卡德相似性度量的对比分析 by ChaoSimple

      1.余弦距离 余弦距离,也称为余弦相似度,是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量. 向量,是多维空间中有方向的线段,如果两个向量的方向一致,即夹角接近零,那么这两个向 ...