structEdge { int to, next; double w; } e[1000000]; int c1, head[maxn]; inlinevoidadd_edge(int u, int v, double w){ e[c1].to = v; e[c1].w = w; e[c1].next = head[u]; head[u] = c1++; }
inlinevoidAdd_edge(int u, int v, double w){ add_edge(u, v, w); add_edge(v, u, 0); }
int s, t, dep[maxn]; boolbfs(){ fill(dep, dep + maxn, 0); dep[s] = 1; queue<int> Q; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; double w = e[i].w; if (w > eps && !dep[v]) { dep[v] = dep[u] + 1; if (v == t) return1; Q.push(v); } } } return0; }
doubledfs(int u, double _w){ if (u == t || _w < eps) return _w; double s = 0; for (int i = head[u]; ~i; i = e[i].next) { int v = e[i].to; double w = e[i].w; if (w > eps && dep[v] == dep[u] + 1) { double di = dfs(v, min(_w - s, w)); e[i].w -= di; e[i ^ 1].w += di; s += di; if (s == _w) break; } } if (s < _w) dep[u] = 0; return s; }
voidwork(){ fill(head, head + maxn, -1); c1 = 0; cin >> n >> m >> p >> k; for (int i = 1; i <= p; ++i) cin >> c[i]; for (int i = 1; i <= m; ++i) for (int j = 1; j <= n; ++j) for (int k = 1; k <= p; ++k) cin >> f[j][i][k]; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { double mul = 1; g[i][j] = 0; for (int k = 1; k <= p; ++k) { mul = mul * f[i][j][k]; g[i][j] += mul * c[k]; } } s = 0; t = n * (m + 1) + 1; for (int i = 1; i <= n; ++i) { Add_edge(s, id(i, 1), INF); Add_edge(id(i, m + 1), t, INF); for (int j = 1; j <= m; ++j) { Add_edge(id(i, j), id(i, j + 1), g[i][j]); Add_edge(id(i, j + 1), id(i, j), INF); } } while (k--) { int x, y, z; cin >> x >> y >> z; for (int i = 1; i <= m + 1; ++i) if (1 <= i + z && i + z <= m + 1) Add_edge(id(y, i), id(x, i + z), INF); } double ans = dinic(); if (ans > INF - 1) cout << "-1\n"; elsecout << fixed << setprecision(4) << ans << "\n"; }