分数规划,二分答案,变成树上依赖背包。
复杂度
O(nklog1e9)
O
(
n
k
l
o
g
1
e
9
)
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 2510
#define eps 1e-4
inline char gc(){
static char buf[1<<16],*S,*T;
if(S==T){T=(S=buf)+fread(buf,1,1<<16,stdin);if(T==S) return EOF;}
return *S++;
}
inline int read(){
int x=0,f=1;char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=gc();
return x*f;
}
int n,K,c[N],w[N],fa[N];
double v[N],f[N][N];
vector<int>son[N];
void dfs(int x){
for(int i=1;i<=K;++i) f[x][i]=f[fa[x]][i-1]+v[x];
for(int i=0;i<son[x].size();++i) dfs(son[x][i]);
for(int i=0;i<=K;++i) f[fa[x]][i]=max(f[fa[x]][i],f[x][i]);
}
inline bool jud(double mid){
for(int i=1;i<=n;++i) v[i]=w[i]-mid*c[i];
for(int i=0;i<=n;++i)
for(int j=0;j<=K;++j) f[i][j]=-1e100;
f[0][0]=0;
for(int i=0;i<son[0].size();++i) dfs(son[0][i]);
return f[0][K]>-eps;
}
int main(){
// freopen("a.in","r",stdin);
K=read();n=read();
for(int i=1;i<=n;++i) c[i]=read(),w[i]=read(),fa[i]=read(),son[fa[i]].push_back(i);
double l=0,r=25e6;
while(r-l>eps){
double mid=(l+r)/2;
if(jud(mid)) l=mid;
else r=mid;
}printf("%.3lf\n",l);
return 0;
}