# [ POI 2017 ] Sabota?

## Solution

$f[i]$ 表示节点 $i$ 不被染黑的最小的 $x$ ，那么合法情况为:

$f[i]=\max_{v\in son[u]} \bigg\{\min\bigg(f[v], \frac{size[v]}{size[u] - 1}\bigg)\bigg\}$

$ans = \max_{size[u]>k}\{f[u]\}$

#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define N 500005
using namespace std;

inline int rd() {
int x = 0;
char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) {
x = x * 10 + (c ^ 48); c = getchar();
}
return x;
}

double ans, f[N];

int n, m, tot, hd[N], sz[N];

struct edge{int to, nxt;} e[N << 1];

inline void add(int u, int v) {
e[++tot].to = v; e[tot].nxt = hd[u]; hd[u] = tot;
e[++tot].to = u; e[tot].nxt = hd[v]; hd[v] = tot;
}

void dfs(int u, int fa) {
sz[u] = 1;
for (int i = hd[u], v; i; i = e[i].nxt)
if ((v = e[i].to) != fa) {
dfs(v, u); sz[u] += sz[v];
}
if (sz[u] == 1) {f[u] = 1.0; return;}
for (int i = hd[u], v; i; i = e[i].nxt)
if ((v = e[i].to) != fa)
f[u] = max(f[u], min(f[v], (double)sz[v] / (sz[u] - 1)));
if (sz[u] > m) ans = max(ans, f[u]);
}

int main() {
n = rd(); m = rd();
for (int i = 2; i <= n; ++i) add(i, rd());
dfs(1, 0);
printf("%.10lf\n", ans);
return 0;
}

posted @ 2019-03-29 11:30  SGCollin  阅读(49)  评论(0编辑  收藏