震惊!dp还能这样用
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=55, maxm=305, INF=0x3f3f3f3f;
int n, m;
struct Edge{
int to, nxt, v;
}e[maxm*2];
int cnte, fir[maxn];
void addedge(int x, int y, int z){
Edge &ed=e[++cnte]; ed.v=z;
ed.to=y; ed.nxt=fir[x]; fir[x]=cnte; }
int f[maxn][25][maxn*maxn];
int sqr(int x){ return x*x; }
inline void up_min(int &x, int y){ if (x>=y) x=y; }
int in[maxn], q[maxn], hd, tl;
void topo(){
for (int i=1; i<=n; ++i) if (!in[i]) q[tl++]=i;
while (hd<tl){
int u=q[hd++];
for (int i=fir[u]; i; i=e[i].nxt){
int v=e[i].to; --in[v];
for (int j=0; j<20; ++j)
for (int k=0; k<2500; ++k)
up_min(f[v][j+1][k+e[i].v], f[u][j][k]+sqr(e[i].v));
if (in[v]==0) q[tl++]=v;
}
}
}
int main(){
scanf("%d %d", &n, &m); int x, y, z;
for (int i=1; i<=m; ++i){
scanf("%d%d%d", &x, &y, &z); ++in[y];
addedge(x, y, z); }
memset(f, 0x3f, sizeof(f));
f[1][0][0]=0; topo(); double ans=INF;
for (int j=1; j<20; ++j)
for (int k=0; k<2500; ++k)
ans=min(ans, (double)(1ll*j*f[n][j][k]-sqr(k))/(j*j));
printf("%.4lf
", ans);
return 0;
}