POJ - 2057 The Lost House(树形DP+贪心)
https://vjudge.net/problem/POJ-2057
题意
有一只蜗牛爬上某个树枝末睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面,。现在这只蜗牛要求寻找它的房子,它又得从树根开始爬起去找房子。现在要求一条路径使得其找到房子所要爬行的期望距离最小。房子等可能的出现在每个树枝末。某些分叉点会有虫子,会告知上次是否路过此地。
分析
有了虫子的存在,会影响我们遍历这棵树的路径,当虫子给出的信息是N时,就没必要走这个子树。所以问题就是设计一个期望值最小的路径。
设从root结点出发,有两个子树A和B,PA是房子在A子树上的概率,PB同理。那么根据遍历顺序不同,得出以下两个式子:
先A后B的期望:【在A子树上找到房子的总路程】*PA+(【在A子树上没有找到房子的总路程】+【在B子树上找到房子的总路程】)*PB
先B后A的期望:【在B子树上找到房子的总路程】*PB+(【在B子树上没有找到房子的总路程】+【在A子树上找到房子的总路程】)*PA
其中没有找到房子的总路程是固定值,即为遍历整个子树的路程(根据虫子的信息)。
那么答案要求期望最小,需要贪心地遍历子树,上述两个式子一比较,
则变成了【在A子树上没有找到房子的总路程】*PB和【在B子树上没有找到房子的总路程】*PA的比较,于是只用将子树进行排序,然后按照此顺序遍历子树必定是最优的了。
设dp[i][0]表示以i为根的子树找不到房子时要爬行总路程。dp[i][1]表示以i为根的子树在选择好所有分支点的爬行方案后,枚举完房子落在该子树所有叶子节点上的总爬行距离的最小值。
那么有动态方程:
num[x]表示x节点一共有多少个孩子节点
dp[i][0] = sum{ dp[j][0] + 2 } 当i没有毛毛虫且要求j是i的孩子节点, 多出来的2就是连接该孩子节点的边来回的两次
dp[i][0] = 0 当该点有毛毛虫的时候, 原因是因为毛毛虫会告诉我们这点下面没有房子
当一个节点时叶子节点的时候,那么 dp[i][0] = dp[i][1] = 0;
要明确dp[i][1]是表示在遇到分支选择的先后顺序决定后,我们枚举房子在其各个叶子
上的所要爬行的总距离
则dp[i][1] = sum{ (sum{dp[1..j-1][0]+2}+1}*num[j] + dp[j][1]}, 其中j是i的孩子
上面的意思翻译过来就是遍历i的孩子中的j号子树所有叶子节点所
要爬行的最短距离,其值就是: 前面[1, j-1]号子树没有找到节点所爬行的最短距离加上走了的多余的边再加上遍历j
号子树所有叶子节点所爬行的最短距离。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define IOS ios::sync_with_stdio(0);cin.tie(0);
#define random(a, b) rand()*rand()%(b-a+1)+a
#define pi acos(-1.0)
//const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
const int maxn = (<<) +;
const int maxm = 1e5 +;
const ll mod = 1e9+;
const double eps = 1e-;
ll qpow(ll a,ll b){ ll res=; for(;b;b>>=,a=a*a%mod) if(b&) res=res*a%mod; return res;} struct ND{
int to,nxt;
}edge[];
int n;
int head[],num[],tot;
bool vis[];
int dp[][];
void addedge(int u,int v){
edge[tot].to=v;
edge[tot].nxt=head[u];
head[u]=tot++;
}
void init(){
ms(head,-);
ms(vis,false);
tot=;
}
int cmp(int a,int b){
return (dp[a][]+)*num[b]<(dp[b][]+)*num[a];
}
void dfs(int u){
int p = head[u];
dp[u][]=dp[u][]=;
num[u]=;
if(p==-){
num[u]++;
}else{
int cnt=,s[];
while(p!=-){
s[cnt++]=edge[p].to;
dfs(edge[p].to);
num[u]+=num[edge[p].to];
if(!vis[u]) dp[u][]+=dp[edge[p].to][]+;
p=edge[p].nxt;
}
sort(s,s+cnt,cmp);
int tmp=;
for(int i=;i<cnt;i++){
dp[u][]+=dp[s[i]][]+(tmp+)*num[s[i]];
tmp+=dp[s[i]][]+;
}
}
}
int main(){
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int fa;
char c;
while(~scanf("%d",&n)&&n){
init();
scanf("%d %c",&fa,&c);
for(int i=;i<=n;i++){
scanf("%d %c",&fa,&c);
addedge(fa,i);
if(c=='Y') vis[i]=true;
}
dfs();
printf("%.4f\n",1.0*dp[][]/num[]);
}
return ;
}
POJ - 2057 The Lost House(树形DP+贪心)的更多相关文章
- POJ 2057 The Lost Home 树形dp 难度:2
The Lost House Time Limit: 3000MS Memory Limit: 30000K Total Submissions: 2203 Accepted: 906 Des ...
- 【bzoj4027】[HEOI2015]兔子与樱花 树形dp+贪心
题目描述 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接,我们可以把它 ...
- POJ 3140.Contestants Division 基础树形dp
Contestants Division Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10704 Accepted: ...
- POJ:2342-Anniversary party(树形dp入门题目)
传送门:http://poj.org/problem?id=2342 Anniversary party Time Limit: 1000MS Memory Limit: 65536K Descrip ...
- [BZOJ1596] [Usaco2008 Jan]电话网络(树形DP || 贪心)
传送门 1.树形DP #include <cstdio> #include <cstring> #include <iostream> #define N 1000 ...
- 树的点分治 (poj 1741, 1655(树形dp))
poj 1655:http://poj.org/problem?id=1655 题意: 给无根树, 找出以一节点为根, 使节点最多的树,节点最少. 题解:一道树形dp,先dfs 标记 所有节点的子 ...
- poj 2342 Anniversary party 简单树形dp
Anniversary party Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3862 Accepted: 2171 ...
- POJ 1155 TELE 背包型树形DP 经典题
由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送 ...
- poj 3140 Contestants Division(树形dp? dfs计数+枚举)
本文出自 http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...
- POJ 3140 Contestants Division 【树形DP】
<题目链接> 题目大意:给你一棵树,让你找一条边,使得该边的两个端点所对应的两颗子树权值和相差最小,求最小的权值差. 解题分析: 比较基础的树形DP. #include <cstdi ...
随机推荐
- requirejs 使用实例r.js打包
在这里,请先看基础文章与相关技术文档: 安装: npm init npm install requirejs --save npm install jquery@1.11.1 --save 创建基本目 ...
- requests中 .text 和 .content区别
import requests url = 'https://www.baidu.com' response = requests.get(url) 1.response.content: 这个是直接 ...
- Linux 多网卡绑定bond
mode=0:负载均衡模式,增加带宽,两块网卡使用的是同一个MAC地址,所以必须配置网卡相连的交换机,这两个端口应采用聚合方式. mode=1:主备模式,一个线断了,另一条自动备援. mode=6:负 ...
- android 异常信息The specified child already has a parent. You must call removeView() on the child's parent first. 的处理方法
[Android异常信息]: The specified child already has a parent. You must call removeView() on the child's p ...
- 【BZOJ4419】[SHOI2013]发微博(???)
[BZOJ4419][SHOI2013]发微博(???) 题面 BZOJ 洛谷 题解 一道\(easy\),每个点维护一下要给周围的点加上多上,如果额外连了一个点进来就给他把标记减掉,如果删掉了一条边 ...
- Balanced Sequence HDU - 6299(杭电多校1 B)
题目说要n个字符串串内随意组合以后将这些串放在一起,然后求最长的括号匹配的长度,并不要求是连续的 因为不需要是连续的,所以可以先把已经匹配好的括号加入到答案里面去,先把这些删掉,以为并不影响结果,然后 ...
- centos7破解安装jira6.3.6(含Agile)
应用场景:JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪.客户服务.需求收集.流程审批.任务跟踪.项目跟踪 和敏捷管理等工作领域. 安装环境:centos7.3虚拟机 ...
- 牛客练习赛43 Tachibana Kanade Loves Game (简单容斥)
链接:https://ac.nowcoder.com/acm/contest/548/F来源:牛客网 题目描述 立华奏是一个天天打比赛的萌新. 省选将至,萌新立华奏深知自己没有希望进入省队,因此开始颓 ...
- dom4j解析xml时取消DTD验证
解决方式整合一下,就分两种: 1.用setFeature() SAXReader reader = new SAXReader();reader.setValidation(false); reade ...
- 任意模数NTT
任意模数\(NTT\) 众所周知,为了满足单位根的性质,\(NTT\)需要质数模数,而且需要能写成\(a2^{k} + r\)且\(2^k \ge n\) 比较常用的有\(998244353,1004 ...