← Home
For problem statement at 1000-1999/1100-1199/1140-1149/1149/problemD.txt this is a correct solution, but verifier at 1000-1999/1100-1199/1140-1149/1149/verifierD.go ends with test 1 failed
input:
3 2 3 7
1 1 7
2 2 3
expected:
1073741824 1073741824 1073741824
but got:
0 -1 -1 can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type Item struct {
	cost int64
	u    int
	mask int
}

type MinHeap struct {
	data []Item
}

func (h *MinHeap) Push(item Item) {
	h.data = append(h.data, item)
	h.up(len(h.data) - 1)
}

func (h *MinHeap) Pop() Item {
	n := len(h.data) - 1
	h.data[0], h.data[n] = h.data[n], h.data[0]
	item := h.data[n]
	h.data = h.data[:n]
	h.down(0, n)
	return item
}

func (h *MinHeap) up(j int) {
	for {
		i := (j - 1) / 2
		if i == j || h.data[j].cost >= h.data[i].cost {
			break
		}
		h.data[i], h.data[j] = h.data[j], h.data[i]
		j = i
	}
}

func (h *MinHeap) down(i0, n int) {
	i := i0
	for {
		j1 := 2*i + 1
		if j1 >= n || j1 < 0 {
			break
		}
		j := j1
		if j2 := j1 + 1; j2 < n && h.data[j2].cost < h.data[j1].cost {
			j = j2
		}
		if h.data[j].cost >= h.data[i].cost {
			break
		}
		h.data[i], h.data[j] = h.data[j], h.data[i]
		i = j
	}
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	scan := func() int {
		scanner.Scan()
		x, _ := strconv.Atoi(scanner.Text())
		return x
	}

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())
	m := scan()
	a := scan()
	b := scan()

	aAdj := make([][]int, n+1)
	bAdj := make([][]int, n+1)

	for i := 0; i < m; i++ {
		u := scan()
		v := scan()
		c := scan()
		if c == a {
			aAdj[u] = append(aAdj[u], v)
			aAdj[v] = append(aAdj[v], u)
		} else {
			bAdj[u] = append(bAdj[u], v)
			bAdj[v] = append(bAdj[v], u)
		}
	}

	comp := make([]int, n+1)
	compNodes := make([][]int, 1)
	cIdx := 1

	for i := 1; i <= n; i++ {
		if comp[i] == 0 {
			comp[i] = cIdx
			q := []int{i}
			nodes := []int{i}
			for head := 0; head < len(q); head++ {
				curr := q[head]
				for _, nxt := range aAdj[curr] {
					if comp[nxt] == 0 {
						comp[nxt] = cIdx
						q = append(q, nxt)
						nodes = append(nodes, nxt)
					}
				}
			}
			compNodes = append(compNodes, nodes)
			cIdx++
		}
	}

	da := make([][]int, n+1)
	for i := 1; i <= n; i++ {
		da[i] = make([]int, n+1)
		for j := 1; j <= n; j++ {
			da[i][j] = -1
		}
		da[i][i] = 0
		q := []int{i}
		for head := 0; head < len(q); head++ {
			curr := q[head]
			for _, nxt := range aAdj[curr] {
				if da[i][nxt] == -1 {
					da[i][nxt] = da[i][curr] + 1
					q = append(q, nxt)
				}
			}
		}
	}

	lid := make([]int, n+1)
	for i := 1; i <= n; i++ {
		lid[i] = -1
	}
	k := 0
	for i := 1; i < cIdx; i++ {
		s := len(compNodes[i])
		if int64(s-1)*int64(a) > 2*int64(b) {
			for _, u := range compNodes[i] {
				lid[u] = k
			}
			k++
		}
	}

	dist := make([][]int64, n+1)
	for i := 1; i <= n; i++ {
		dist[i] = make([]int64, 1<<k)
		for j := 0; j < (1 << k); j++ {
			dist[i][j] = -1
		}
	}

	startMask := 0
	if lid[1] != -1 {
		startMask = 1 << lid[1]
	}
	dist[1][startMask] = 0

	heap := &MinHeap{data: make([]Item, 0, 1000000)}
	heap.Push(Item{cost: 0, u: 1, mask: startMask})

	for len(heap.data) > 0 {
		curr := heap.Pop()
		if curr.cost > dist[curr.u][curr.mask] {
			continue
		}

		cu := comp[curr.u]
		for _, v := range compNodes[cu] {
			if da[curr.u][v] == -1 {
				continue
			}
			costV := curr.cost + int64(da[curr.u][v])*int64(a)

			if dist[v][curr.mask] == -1 || costV < dist[v][curr.mask] {
				dist[v][curr.mask] = costV
				heap.Push(Item{cost: costV, u: v, mask: curr.mask})
			}

			for _, w := range bAdj[v] {
				if comp[v] == comp[w] {
					continue
				}
				wLid := lid[w]
				if wLid != -1 && (curr.mask&(1<<wLid)) != 0 {
					continue
				}
				nextMask := curr.mask
				if wLid != -1 {
					nextMask |= (1 << wLid)
				}
				nextCost := costV + int64(b)
				if dist[w][nextMask] == -1 || nextCost < dist[w][nextMask] {
					dist[w][nextMask] = nextCost
					heap.Push(Item{cost: nextCost, u: w, mask: nextMask})
				}
			}
		}
	}

	ans := make([]int64, n+1)
	for p := 1; p <= n; p++ {
		ans[p] = -1
		for mask := 0; mask < (1 << k); mask++ {
			if dist[p][mask] != -1 {
				if ans[p] == -1 || dist[p][mask] < ans[p] {
					ans[p] = dist[p][mask]
				}
			}
		}
	}

	for p := 1; p <= n; p++ {
		fmt.Print(ans[p])
		if p < n {
			fmt.Print(" ")
		}
	}
	fmt.Println()
}