constint N = 2500 + 5; constint M = 1e4 + 5; constint INF = 0x3f3f3f3f;
int n, m, K; LL a[N]; structEdge { int to, nxt; } edge[M << 1]; int head[N]; voidadd_edge(int u, int v){ staticint k = 1; edge[k] = (Edge){v, head[u]}, head[u] = k++; }
int dis[N][N]; bool vis[N]; std::queue<int> q; voidbfs(int st){ while(!q.empty()) q.pop(); for(int i = 1; i <= n; i++) vis[i] = false, dis[st][i] = INF; dis[st][st] = 0, vis[st] = true, q.push(st); while(!q.empty()) { int u = q.front(); q.pop(); for(int i = head[u]; i; i = edge[i].nxt) { int v = edge[i].to; if(vis[v]) continue; dis[st][v] = dis[st][u] + 1, vis[v] = true, q.push(v); } } }
bool e[N][N]; int r[N][3];
voidprint(Lint x){ char stk[200]; int top = 0; if(x == 0) stk[top++] = '0'; while(x) stk[top++] = x % 10 + '0', x /= 10; for(top--; top >= 0; top--) putchar(stk[top]); }
int n, K, Q; LL a[N]; structEdge { int to, nxt; } edge[N << 1]; int head[N]; voidadd_edge(int u, int v){ staticint k = 1; edge[k] = (Edge){v, head[u]}, head[u] = k++; }
int fa[N], dep[N], son[N]; voiddfs(int u){ dep[u] = dep[fa[u]] + 1; for(int i = head[u]; i; i = edge[i].nxt) if(edge[i].to != fa[u]) { int v = edge[i].to; fa[v] = u; dfs(v); if(!son[u] || a[son[u]] > a[v]) son[u] = v; } }
structMatrix { LL a[3][3]; } e, initial; Matrix mul(Matrix x, Matrix y){ Matrix z; for(int i = 0; i < K; i++) for(int j = 0; j < K; j++) z.a[i][j] = LLINF; for(int i = 0; i < K; i++) for(int j = 0; j < K; j++) for(int k = 0; k < K; k++) z.a[i][k] = std::min(z.a[i][k], x.a[i][j] + y.a[j][k]); return z; } Matrix trans[N];
Matrix prod1[N][21], prod2[N][21]; int go[N][21]; voidpreprocess(){ for(int i = 1; i <= n; i++) go[i][0] = fa[i], prod1[i][0] = prod2[i][0] = trans[i]; for(int j = 1; j <= 20; j++) for(int i = 1; i <= n; i++) { go[i][j] = go[go[i][j - 1]][j - 1]; prod1[i][j] = mul(prod1[i][j - 1], prod1[go[i][j - 1]][j - 1]); prod2[i][j] = mul(prod2[go[i][j - 1]][j - 1], prod2[i][j - 1]); } } intlca(int u, int v){ if(dep[u] < dep[v]) std::swap(u, v); int d = dep[u] - dep[v]; for(int i = 0; i <= 20; i++) if(d >> i & 1) u = go[u][i]; if(u == v) return u; for(int i = 20; i >= 0; i--) if(go[u][i] != go[v][i]) u = go[u][i], v = go[v][i]; return fa[u]; } Matrix multiply1(int u, int d){ Matrix x = e; for(int i = 0; i <= 20; i++) if(d >> i & 1) x = mul(x, prod1[u][i]), u = go[u][i]; return x; } Matrix multiply2(int u, int d){ Matrix x = e; for(int i = 0; i <= 20; i++) if(d >> i & 1) x = mul(prod2[u][i], x), u = go[u][i]; return x; }
intmain(){ freopen("transmit.in", "r", stdin); freopen("transmit.out", "w", stdout); scanf("%d%d%d", &n, &Q, &K); for(int i = 1; i <= n; i++) scanf("%lld", &a[i]); for(int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); add_edge(u, v), add_edge(v, u); } dfs(1); for(int i = 0; i < K; i++) for(int j = 0; j < K; j++) e.a[i][j] = (i == j ? 0 : LLINF); for(int i = 0; i < K; i++) for(int j = 0; j < K; j++) initial.a[i][j] = LLINF; initial.a[0][K - 1] = 0; for(int i = 1; i <= n; i++) { for(int j = 0; j < K; j++) for(int k = 0; k < K; k++) trans[i].a[j][k] = LLINF; trans[i].a[0][0] = a[i]; if(K >= 2) trans[i].a[0][1] = 0, trans[i].a[1][0] = a[i]; if(K >= 3) trans[i].a[1][2] = 0, trans[i].a[2][0] = a[i], trans[i].a[1][1] = (son[i] ? a[son[i]] : LLINF); } preprocess(); while(Q--) { int u, v; scanf("%d%d", &u, &v); int f = lca(u, v); int du = dep[u] - dep[f] + 1, dv = dep[v] - dep[f] + 1; LL ans = mul(initial, mul(multiply1(u, du), multiply2(v, dv - 1))).a[0][0]; if(fa[f]) ans = std::min(ans, mul(initial, mul(multiply1(u, du + 1), multiply2(v, dv))).a[0][0]); printf("%lld\n", ans); } return0; }