[POI2017]Sabotaż
2018-09-01 19:58
204 查看
[POI2017]Sabotaż
题目大意:
一棵\(n(n\le5\times10^5)\)个结点的树,初始时有一个未知的黑点,其余全为白点。对于一个点,如果其子树中黑点所占比例超过\(x\),则这整棵子树也都会变成黑点。求最小的\(x\),使得最坏情况下,黑点的个数不会超过\(k\)。
思路:
树形DP。
\(f[i]\)表示无法使\(i\)子树全黑的最大\(x\)。
\(f[i]=\max\{\min(f[j],\frac{size[j]}{size[i]-1})\}\),其中\(j\)为\(i\)的子结点。
时间复杂度\(\mathcal O(n)\)。
源代码:
#include<cstdio> #include<cctype> #include<vector> inline int getint() { register char ch; while(!isdigit(ch=getchar())); register int x=ch^'0'; while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); return x; } const int N=5e5+1; int n,k,size ; double f ,ans; std::vector<int> e ; void dfs(const int &x) { for(unsigned i=0;i<e[x].size();i++) { const int &y=e[x][i]; dfs(y); size[x]+=size[y]; } for(register unsigned i=0;i<e[x].size();i++) { const int &y=e[x][i]; f[x]=std::max(f[x],std::min(f[y],size[y]*1./size[x])); } size[x]++; if(size[x]==1) f[x]=1; if(size[x]>k) ans=std::max(ans,f[x]); } int main() { n=getint(),k=getint(); for(register int i=2;i<=n;i++) { e[getint()].push_back(i); } dfs(1); printf("%.8f\n",ans); return 0; }
相关文章推荐
- BZOJ4726: [POI2017]Sabota?
- 【BZOJ4726】[POI2017]Sabota? 树形DP
- bzoj4726 [POI2017]Sabota?
- 【bzoj4726】[POI2017]Sabota? 树形dp
- BZOJ 4726: [POI2017]Sabota? 树形dp
- BZOJ 4726: [POI2017]Sabota?
- BZOJ4726: [POI2017]Sabota?
- 【BZOJ4723】【POI2017】Sabota?
- BZOJ4726 [POI2017]Sabota?
- 4726: [POI2017]Sabota?
- 【POI2017||bzoj4726】Sabota?
- 【BZOJ】4726 [POI2017] Sabota?
- [bzoj4726][POI2017][Sabota?] (树形dp)
- [BZOJ]4726 [POI2017] Sabota? 树形Dp
- bzoj 4726: [POI2017]Sabota? 树形dp
- BZOJ_4726_[POI2017]Sabota?_树形DP
- BZOJ4726 [POI2017][Sabota?] 树形DP
- BZOJ 4726: [POI2017]Sabota?【树形dp
- [bzoj4726][POI2017]Sabota?
- BZOJ 4726 [POI2017] Sabota?