#ifdef ssu1 #define _GLIBCXX_DEBUG #endif #undef NDEBUG #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define fore(i, l, r) for(int i = (l); i < (r); ++i) #define forn(i, n) fore(i, 0, n) #define fori(i, l, r) fore(i, l, (r) + 1) #define sz(v) int((v).size()) #define all(v) (v).begin(), (v).end() #define pb push_back #define mp make_pair #define X first #define Y second #if ( _WIN32 || __WIN32__ ) #define LLD "%I64d" #else #define LLD "%lld" #endif typedef long long li; typedef long double ld; typedef pair pt; template T abs(T a) { return a < 0 ? -a : a; } template T sqr(T a) { return a*a; } const ld EPS = 1e-9; const ld PI = 3.1415926535897932384626433832795; /* This is just to check correctness of input */ int readInt(int l, int r){ int x; if(scanf("%d", &x) != 1){ fprintf(stderr, "Expected int in range [%d, %d], but haven't found!", l, r); throw; } if(!(l <= x && x <= r)){ fprintf(stderr, "Expected int in range [%d, %d], but found %d!", l, r, x); throw; } return x; } int readInt(int l, int r, string name){ int x; if(scanf("%d", &x) != 1){ fprintf(stderr, "Expected int %s in range [%d, %d], but haven't found!", name.c_str(), l, r); throw; } if(!(l <= x && x <= r)){ fprintf(stderr, "Expected int %s in range [%d, %d], but found %d!", name.c_str(), l, r, x); throw; } return x; } li readLong(li l, li r){ li x; if(scanf(LLD, &x) != 1){ fprintf(stderr, "Expected long long in range ["LLD", "LLD"], but haven't found!", l, r); throw; } if(!(l <= x && x <= r)){ fprintf(stderr, "Expected long long in range ["LLD", "LLD"], but found "LLD"!", l, r, x); throw; } return x; } li readLong(li l, li r, string name){ li x; if(scanf(LLD, &x) != 1){ fprintf(stderr, "Expected long long %s in range ["LLD", "LLD"], but haven't found!", name.c_str(), l, r); throw; } if(!(l <= x && x <= r)){ fprintf(stderr, "Expected long long %s in range ["LLD", "LLD"], but found "LLD"!", name.c_str(), l, r, x); throw; } return x; } const ld __EPS__ = 1e-15; ld readDouble(double l, double r){ double x; if(scanf("%lf", &x) != 1){ fprintf(stderr, "Expected double in range [%lf, %lf], but haven't found!", l, r); throw; } if(!(l <= x + __EPS__ && x <= r + __EPS__)){ fprintf(stderr, "Expected double in range [%lf, %lf], but found %lf!", l, r, x); throw; } return x; } ld readDouble(double l, double r, string name){ double x; if(scanf("%lf", &x) != 1){ fprintf(stderr, "Expected double %s in range [%lf, %lf], but haven't found!", name.c_str(), l, r); throw; } if(!(l <= x + __EPS__ && x <= r + __EPS__)){ fprintf(stderr, "Expected double %s in range [%lf, %lf], but found %lf!", name.c_str(), l, r, x); throw; } return x; } const int NMAX = 200000; const int GMAX = 200000; const int INF = 2e9; struct edge{ int to, c, f, d, rev; }; vector g[GMAX]; void add_edge(int v, int u, int cap, int dist){ edge fw = {u, cap, 0, dist, sz(g[u])}; edge bw = {v, 0, 0, -dist, sz(g[v])}; g[v].pb(fw), g[u].pb(bw); } int p[GMAX], mf[GMAX], d[GMAX], pe[GMAX], inq[GMAX], q[GMAX], hq, tq, cntg; bool enlarge(int s, int t, int& flow, int& fcost){ forn(i, cntg + 10) d[i] = INF; hq = tq = 0; mf[s] = INF, d[s] = 0, p[s] = pe[s] = -1, q[tq++] = s, inq[s] = true; while(hq != tq){ int v = q[hq++]; inq[v] = false; if(hq == GMAX) hq = 0; forn(i, sz(g[v])){ const edge& u = g[v][i]; if(u.c - u.f > 0 && d[u.to] > d[v] + u.d){ d[u.to] = d[v] + u.d; mf[u.to] = min(mf[v], u.c - u.f); p[u.to] = v, pe[u.to] = i; if(!inq[u.to]){ inq[u.to] = true; q[tq++] = u.to; if(tq == GMAX) tq = 0; } } } } if(d[t] == INF) return false; // cerr << mf[t] << " " << d[t] << endl; flow += mf[t]; fcost += mf[t] * d[t]; for(int v = t; v != s; v = p[v]){ g[p[v]][pe[v]].f += mf[t]; g[v][g[p[v]][pe[v]].rev].f -= mf[t]; } return true; } int n, cnt[NMAX], used[NMAX], cntu = 0; vector t[NMAX]; void dfs(int v, int pv){ used[v] = 1; cntu++; forn(i, sz(t[v])){ int u = t[v][i]; if(used[u]) continue; cnt[v]++; dfs(u, v); } } int v[NMAX]; bool cmp(int a, int b){ return v[a] < v[b]; } int main(){ #ifdef ssu1 // assert(freopen("input.txt", "rt", stdin)); //assert(freopen("output.txt", "wt", stdout)); #endif n = readInt(1, 100000, "n"); forn(i, n){ v[i] = readInt(1, 1000, "v[i]"); } forn(i, n - 1){ int a = readInt(1, n, "a[i]") - 1, b = readInt(1, n, "b[i]") - 1; t[a].pb(b); t[b].pb(a); } dfs(0, -1); assert(cntu == n); vector order; forn(i, n) order.pb(i); sort(all(order), cmp); int qs = readInt(1, 100, "qs"); forn(qi, qs){ int m = readInt(1, 100, "m"), x = readInt(1, 1000, "x"), y = readInt(1, 1000, "y"); vector nv(m); forn(i, m) nv[i] = readInt(1, 1000, "nv[i]"); vector ok1, ok2, okv; forn(i, n){ int v = order[i]; if(cnt[v] < x){ ok1.pb(v); }else ok2.pb(v); } while(sz(ok1) > m) ok1.pop_back(); while(sz(ok2) > 1) ok2.pop_back(); okv = ok1; okv.insert(okv.end(), all(ok2)); cntg = sz(okv) + 2*m + 2; int S = cntg - 2, T = cntg - 1; forn(i, sz(okv)){ int v = okv[i]; if(cnt[v] < x){ add_edge(S, i, x - cnt[v], 0); } add_edge(S, i, m + 1, y); } forn(i, m){ add_edge(S, i + sz(okv), x, 0); add_edge(S, i + sz(okv), m + 1, y); } forn(i, sz(okv)){ int vx = okv[i]; forn(j, m){ add_edge(i, j + sz(okv) + m, 1, v[vx] * nv[j]); // cerr << v[vx] << " " << nv[j] << endl; } } forn(i, m){ fore(j, i + 1, m){ add_edge(i + sz(okv), j + sz(okv) + m, 1, nv[i] * nv[j]); // cerr << nv[i] << " " << nv[j] << endl; } } forn(i, m){ add_edge(i + sz(okv) + m, T, 1, 0); } int F = 0, FC = 0; while(enlarge(S, T, F, FC)); assert(F == m); printf("%d\n", FC); forn(i, cntg) g[i].clear(); } return 0; }