Description
学校科技楼一共有
N
层,而神犇YJQ每天都在科技楼
Input Description
第一行包含
2
个整数
Output Description
一行
Sample Input
4 4 1 2 1 2 4 3 1 3 2 3 4 3
Sample Output
0.2500
Data Size & Hint
对于
另有 20% 的数据 N≤35,M≤220,Z∈[0,1] ;
对于
100%
的数据
2≤N≤50,M≤300,0≤Z≤50
保证至少存在一条由
1
到
Solution
方差为 s2
- s2=∑(xi−x¯)2n=(∑x2i)−2x¯(∑xi)+nx¯2n
那么在
∑xi
一定时,
∑x2i
最小时方差最小。
于是
f[i][j][k]
表示走到
i
号点,走了
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define drp(i, a, b) for (int i = a; i >= b; i--)
inline int read() {
int x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') flag = -1; ch = getchar(); }
while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag;
}
inline void write(int x) {
if (!x) { putchar('0'); return; } if (x < 0) putchar('-'), x = -x;
char buf[20] = ""; int top = 0; while (x) buf[++top] = x % 10 + '0', x /= 10; while (top) putchar(buf[top--]);
}
struct edge { int v, w, next; }e[501]; int tot;
int n, g[501];
int dp[51][21][16001], INF = 1000000007;
int deg[51], sum;
int q[5000], r, l = 1;
inline void add(int u, int v, int w) { e[++tot] = edge{ v, w, g[u] }; g[u] = tot; deg[v]++; sum += w; }
#define Min(a, b) a = min(a, b)
void topu() {
rep(i, 1, n) if(!deg[i]) q[++r] = i;
dp[1][0][0] = 0;
while(l <= r) {
int u = q[l++];
rep(j, 0, 19) rep(k, 0, sum) if(dp[u][j][k] ^ INF) for(int i = g[u]; i; i = e[i].next) {
int v = e[i].v, w = e[i].w;
if(k + w <= sum) Min(dp[v][j + 1][k + w], dp[u][j][k] + w * w);
}
for(int i = g[u]; i; i = e[i].next) if(!--deg[e[i].v]) q[++r] = e[i].v;
}
}
int main() {
n = read(); int m = read();
while(m--) { int u = read(), v = read(); add(u, v, read()); }
memset(dp, 127, sizeof dp); INF = dp[0][0][0];
topu();
double ans = 1e9;
rep(j, 1, 20) rep(k, 0, sum) Min(ans,(dp[n][j][k] * 1.0 / j) - (k * 1.0 * k) / (j * 1.0 * j));
printf("%.4lf", ans);
return 0;
}