← Home
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
)

const L = 20
const INF32 int32 = 1 << 30

var (
	n int

	a []int32

	head []int32
	to   []int32
	nxt  []int32

	blocked []bool
	tmpPar  []int32
	subsz   []int32

	order     []int32
	stackNode []int32
	stackPar  []int32
	stackDist []int32
	visitD    []int32
	tempBest  []int32

	pathCent []int32
	pathDist []int32
	pathLen  []uint8

	bestOff  []int32
	bestLen  []int32
	bestFlat []int32
)

func build(start int32) {
	top := 0
	stackNode[top] = start
	top++
	tmpPar[start] = 0
	m := 0

	for top > 0 {
		top--
		x := stackNode[top]
		order[m] = x
		m++
		for e := head[x]; e != -1; e = nxt[e] {
			y := to[e]
			if blocked[y] || y == tmpPar[x] {
				continue
			}
			tmpPar[y] = x
			stackNode[top] = y
			top++
		}
	}

	centroid := start
	bestBal := m + 1

	for i := m - 1; i >= 0; i-- {
		x := order[i]
		sz := 1
		maxPart := 0
		for e := head[x]; e != -1; e = nxt[e] {
			y := to[e]
			if blocked[y] || tmpPar[y] != x {
				continue
			}
			sy := int(subsz[y])
			sz += sy
			if sy > maxPart {
				maxPart = sy
			}
		}
		subsz[x] = int32(sz)
		rest := m - sz
		if rest > maxPart {
			maxPart = rest
		}
		if maxPart < bestBal {
			bestBal = maxPart
			centroid = x
		}
	}

	top = 0
	stackNode[top] = centroid
	stackPar[top] = 0
	stackDist[top] = 0
	top++
	t := 0
	maxD := 0

	for top > 0 {
		top--
		x := stackNode[top]
		p := stackPar[top]
		d := stackDist[top]

		order[t] = x
		visitD[t] = d
		t++

		if int(d) > maxD {
			maxD = int(d)
		}

		idx := int(x)*L + int(pathLen[x])
		pathCent[idx] = centroid
		pathDist[idx] = d
		pathLen[x]++

		for e := head[x]; e != -1; e = nxt[e] {
			y := to[e]
			if blocked[y] || y == p {
				continue
			}
			stackNode[top] = y
			stackPar[top] = x
			stackDist[top] = d + 1
			top++
		}
	}

	for i := 0; i <= maxD; i++ {
		tempBest[i] = INF32
	}
	for i := 0; i < t; i++ {
		x := order[i]
		d := visitD[i]
		if a[x] < tempBest[d] {
			tempBest[d] = a[x]
		}
	}
	for i := 1; i <= maxD; i++ {
		if tempBest[i-1] < tempBest[i] {
			tempBest[i] = tempBest[i-1]
		}
	}

	bestOff[centroid] = int32(len(bestFlat))
	bestLen[centroid] = int32(maxD + 1)
	bestFlat = append(bestFlat, tempBest[:maxD+1]...)

	blocked[centroid] = true
	for e := head[centroid]; e != -1; e = nxt[e] {
		y := to[e]
		if !blocked[y] {
			build(y)
		}
	}
}

type FastScanner struct {
	data []byte
	idx  int
}

func (fs *FastScanner) NextInt() int {
	for fs.idx < len(fs.data) && (fs.data[fs.idx] < '0' || fs.data[fs.idx] > '9') {
		fs.idx++
	}
	val := 0
	for fs.idx < len(fs.data) && fs.data[fs.idx] >= '0' && fs.data[fs.idx] <= '9' {
		val = val*10 + int(fs.data[fs.idx]-'0')
		fs.idx++
	}
	return val
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	fs := FastScanner{data: data}

	n = fs.NextInt()

	a = make([]int32, n+1)

	head = make([]int32, n+1)
	for i := range head {
		head[i] = -1
	}
	to = make([]int32, 2*(n-1))
	nxt = make([]int32, 2*(n-1))

	globalMin := INF32
	var minNode int32

	for i := 1; i <= n; i++ {
		w := int32(fs.NextInt())
		a[i] = w
		if w < globalMin {
			globalMin = w
			minNode = int32(i)
		}
	}

	var edgeIdx int32
	for i := 0; i < n-1; i++ {
		u := int32(fs.NextInt())
		v := int32(fs.NextInt())

		to[edgeIdx] = v
		nxt[edgeIdx] = head[u]
		head[u] = edgeIdx
		edgeIdx++

		to[edgeIdx] = u
		nxt[edgeIdx] = head[v]
		head[v] = edgeIdx
		edgeIdx++
	}

	blocked = make([]bool, n+1)
	tmpPar = make([]int32, n+1)
	subsz = make([]int32, n+1)

	order = make([]int32, n)
	stackNode = make([]int32, n)
	stackPar = make([]int32, n)
	stackDist = make([]int32, n)
	visitD = make([]int32, n)
	tempBest = make([]int32, n)

	pathCent = make([]int32, (n+1)*L)
	pathDist = make([]int32, (n+1)*L)
	pathLen = make([]uint8, n+1)

	bestOff = make([]int32, n+1)
	bestLen = make([]int32, n+1)
	bestFlat = make([]int32, 0, n*L)

	build(1)

	radii := make([]int32, 0, 20)
	for r := int32(1); ; r <<= 1 {
		radii = append(radii, r)
		if int(r) >= n-1 {
			break
		}
	}

	var ans int64
	for u := 1; u <= n; u++ {
		if int32(u) == minNode {
			continue
		}
		aw := a[u]
		best := int64(1 << 62)
		base := u * L
		depth := int(pathLen[u])

		for k := 0; k < len(radii); k++ {
			R := radii[k]
			mn := aw

			for i := 0; i < depth; i++ {
				du := pathDist[base+i]
				if du > R {
					continue
				}
				c := pathCent[base+i]
				rem := int(R - du)
				l := int(bestLen[c])
				if rem >= l {
					rem = l - 1
				}
				w := bestFlat[int(bestOff[c])+rem]
				if w < mn {
					mn = w
				}
			}

			if mn < aw {
				cand := int64(aw) + int64(k+1)*int64(mn)
				if cand < best {
					best = cand
				}
				if mn == globalMin {
					break
				}
			}
		}

		ans += best
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	out.WriteString(strconv.FormatInt(ans, 10))
	out.WriteByte('\n')
	out.Flush()
}