結果
| 問題 |
No.3111 Toll Optimization
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-04-20 03:45:14 |
| 言語 | Go (1.23.4) |
| 結果 |
AC
|
| 実行時間 | 380 ms / 5,000 ms |
| コード長 | 3,309 bytes |
| コンパイル時間 | 12,975 ms |
| コンパイル使用メモリ | 236,116 KB |
| 実行使用メモリ | 34,764 KB |
| 最終ジャッジ日時 | 2025-04-20 03:45:44 |
| 合計ジャッジ時間 | 24,770 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 70 |
ソースコード
package main
import (
"bufio"
"fmt"
"os"
)
var reader *bufio.Reader = bufio.NewReader(os.Stdin)
var writer *bufio.Writer = bufio.NewWriter(os.Stdout)
func printf(format string, a ...interface{}) { fmt.Fprintf(writer, format, a...) }
func scanf(format string, a ...interface{}) { fmt.Fscanf(reader, format, a...) }
func getInt(num *int) {
scanf("%d\n", num)
}
func getInt2(num *int, num2 *int) {
scanf("%d %d\n", num, num2)
}
func getInt3(num *int, num2 *int, num3 *int) {
scanf("%d %d %d\n", num, num2, num3)
}
func getArrInt(arr []int, n int) {
for i := 0; i < n; i++ {
scanf("%d", &arr[i])
}
scanf("\n")
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
type Data struct {
value int
prev int
u int
used int
}
type MinHeap struct {
data []Data
}
func (mh *MinHeap) IsEmpty() bool {
return len(mh.data) == 0
}
func (mh *MinHeap) heapifyUp(node int) {
for node > 0 {
parent := (node - 1) / 2
if mh.data[node].value >= mh.data[parent].value {
break
}
mh.data[node], mh.data[parent] = mh.data[parent], mh.data[node]
node = parent
}
}
func (mh *MinHeap) Push(data Data) {
mh.data = append(mh.data, data)
mh.heapifyUp(len(mh.data) - 1)
}
func (mh *MinHeap) heapifyDown(node int) {
for {
next := node
left := 2*node + 1
right := 2*node + 2
if left < len(mh.data) && mh.data[left].value < mh.data[next].value {
next = left
}
if right < len(mh.data) && mh.data[right].value < mh.data[next].value {
next = right
}
if next == node {
break
}
mh.data[node], mh.data[next] = mh.data[next], mh.data[node]
node = next
}
}
func (mh *MinHeap) Pop() {
if mh.IsEmpty() {
return
}
mh.data[0] = mh.data[len(mh.data)-1]
mh.data = mh.data[:len(mh.data)-1]
mh.heapifyDown(0)
}
func (mh *MinHeap) Peek() Data {
return mh.data[0]
}
func solve() {
var n, m, k int
getInt3(&n, &m, &k)
values := make([]int, m)
getArrInt(values, m)
edges := make(map[int][][2]int, m)
for i := 0; i < m; i++ {
var u, v int
getInt2(&u, &v)
edges[u] = append(edges[u], [2]int{v, values[i]})
edges[v] = append(edges[v], [2]int{u, values[i]})
}
const inf = int(1e18)
memo := make([][]int, n+1)
for i := range memo {
memo[i] = make([]int, k+1)
for j := range memo[i] {
memo[i][j] = inf
}
}
memo[1][0] = 0
minHeap := MinHeap{}
minHeap.Push(Data{
value: 0,
prev: 0,
u: 1,
used: 0,
})
for !minHeap.IsEmpty() {
cur := minHeap.Peek()
minHeap.Pop()
if cur.value > memo[cur.u][cur.used] {
continue
}
for _, e := range edges[cur.u] {
v, cost := e[0], e[1]
if v == cur.prev {
continue
}
// Option 1: use free pass if available
if cur.used < k && cur.value < memo[v][cur.used+1] {
memo[v][cur.used+1] = cur.value
minHeap.Push(Data{
value: cur.value,
prev: cur.u,
u: v,
used: cur.used + 1,
})
}
// Option 2: pay the cost
if cur.value+cost < memo[v][cur.used] {
memo[v][cur.used] = cur.value + cost
minHeap.Push(Data{
value: cur.value + cost,
prev: cur.u,
u: v,
used: cur.used,
})
}
}
}
result := inf
for i := 0; i <= k; i++ {
result = min(result, memo[n][i])
}
if result == inf {
result = -1
}
printf("%d\n", result)
}
func main() {
defer writer.Flush()
solve()
}