BZOJ4726 [POI2017][Sabota?] 树形DP
2017-10-18 21:56
351 查看
状态:
f [u] 表示 u 不叛变的最小 x 值
方程:
f [u] = max { min ( f [v] , size [v] / ( size [u] - 1 ) ) }
解释方程:
1.为什么取max?
—–因为 f [v] 表示的是 v 结点的最小答案,f [u] 不能比 f [v] 小。
2.min{ f [v] , size [v] / ( size [u] - 1 } 表示什么?
——表示 v 的两种状态下的值 : 全是叛徒/v没当叛徒
#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 5e5 + 100 ; double f , mx; int sz ; vector <int> G ; int n , k ; void dfs ( int u , int fa ){ sz [u] = 1 ; for ( int i = 0 ; i < G [u].size () ; ++ i ) { int v = G [u] [i] ; if ( v == fa ) continue ; dfs ( v , u ) ; sz [u] += sz [v] ; } if ( sz [u] == 1 ) f [u] = 1.0 ; else f [u] = 0.0 ; for ( int i = 0 ; i < G [u].size () ; ++ i ) { int v = G [u] [i] ; if ( v == fa ) continue ; f [u] = max ( f [u] , min ( f [v] , (double) sz [v] / ( sz [u] - 1 ) ) ) ; // printf ( "%d %lf\n" , u , f [u] ) ; } if ( sz [u] > k ) mx = max ( mx , f [u] ) ; } int main (){ scanf ( "%d%d" , &n , &k ) ; for ( int i = 2 ; i <= n ; ++ i ){ int x ; scanf ( "%d" , &x ) ; G [x].push_back ( i ) ; } dfs ( 1 , 0 ) ; printf ( "%lf" , mx ) ; return 0 ; }
相关文章推荐
- BZOJ 4726: [POI2017]Sabota?【树形dp
- BZOJ 4726: [POI2017]Sabota? 树形dp
- bzoj 4726: [POI2017]Sabota? 树形dp
- BZOJ 4726 POI2017 Sabota? 树形DP
- 【bzoj4726】[POI2017]Sabota? 树形dp
- 【BZOJ4726】【树形期望DP】[POI2017]Sabota? 题解
- [BZOJ]4726 [POI2017] Sabota? 树形Dp
- [bzoj4726][POI2017][Sabota?] (树形dp)
- 【BZOJ4726】[POI2017]Sabota? 树形DP
- BZOJ_4726_[POI2017]Sabota?_树形DP
- 【BZOJ-4726】Sabota? 树形DP
- [BZOJ 4726] Sabota? 树形DP+贪心思想
- [bzoj4726][POI2017]Sabota?
- BZOJ 4726 [POI2017] Sabota?
- BZOJ4726 [POI2017]Sabota?
- bzoj 4726(树形dp)
- BZOJ 4726: [POI2017]Sabota?
- 【BZOJ】4726 [POI2017] Sabota?
- 【POI2017||bzoj4726】Sabota?
- bzoj4726 [POI2017]Sabota 二分+暴力