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 ...
随机推荐
- Game HDU - 3657(最小割)
Game Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- Random Maze HDU - 4067(预定义状态建边(贪心建边))
Random Maze Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- Ionic3 新增 Service
service是单例模式的 新增Service类 search.service.ts import {Injectable} from '@angular/core'; @Injectable() e ...
- 【cf789C】Functions again(最大子序列和)
C.Functions again 题意 给你一个数组a[1..n].有一个函数\(f(l,r)=\sum_{i=l}^{r-1}\left| a[i]-a[i+1]\right| (-1)^{l-i ...
- Debian 系统安装 Nagios 服务器监控端
安装apt-get updateapt-get install nagios* perlapt-get install --no-install-recommends pnp4nagiosapt-ge ...
- CS academy Binary Flips(dp)
开学啦,没啥时间写博客..过几天就能又停课啦qwq 做点中等 \(dp\) 题来找找 noip 的感觉 233 题意 原题戳这里. 给你一个 \(n \times m\) 的矩阵 \(A\) ,一开始 ...
- 【BZOJ5197】Gambling Guide (最短路,期望)
[BZOJ5197]Gambling Guide (最短路,期望) 题面 BZOJ权限题 洛谷 题解 假设我们求出了每个点的期望,那么对于一个点,只有向期望更小的点移动的时候才会更新答案. 即转移是: ...
- js中获取css样式属性值
关于js中style,currentStyle和getComputedStyle几个注意的地方 (1)用js的style只能获取元素的内联样式,内部样式和外部样式使用style是获取不到的.针对css ...
- BZOJ3456 城市规划 【多项式求ln】
题目链接 BZOJ3456 题解 真是一道经典好题,至此已经写了分治\(NTT\),多项式求逆,多项式求\(ln\)三种写法 我们发现我们要求的是大小为\(n\)无向联通图的数量 而\(n\)个点的无 ...
- 「FJOI2016」神秘数 解题报告
「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...