Submission #51642735


Source Code Expand

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"

	"github.com/liyue201/gostl/ds/priorityqueue"
)

type Edge struct {
	from int
	to   int
	cost float64
}

type Node struct {
	value int
	prev  *Node
	next  *Node
}

type UniqueDoublyLinkedList struct {
	head     *Node
	tail     *Node
	accessor map[int]*Node
	len      int
}

func newLinkedList() *UniqueDoublyLinkedList {
	return &UniqueDoublyLinkedList{
		head:     nil,
		tail:     nil,
		accessor: make(map[int]*Node),
	}
}

func (ll *UniqueDoublyLinkedList) add(value int) {
	node := &Node{value: value}
	if ll.head == nil {
		ll.head = node
		ll.tail = node
	} else {
		ll.tail.next = node
		node.prev = ll.tail
		ll.tail = node
	}
	ll.accessor[value] = node
	ll.len++
}

func (ll *UniqueDoublyLinkedList) insertAfter(preValue int, value int) {
	preNode := ll.accessor[preValue]
	node := &Node{value: value}
	node.prev = preNode
	node.next = preNode.next
	if preNode == ll.tail {
		ll.tail = node
	} else {
		preNode.next.prev = node
	}
	preNode.next = node
	ll.len++
	ll.accessor[value] = node
}

func (ll *UniqueDoublyLinkedList) has(value int) bool {
	_, ok := ll.accessor[value]
	return ok
}

func main() {
	n := readInt()
	XY := make([][2]int, n)
	for i := 0; i < n; i++ {
		scanIntVariables(&XY[i][0], &XY[i][1])
	}
	D := make([][]float64, n)
	for i := 0; i < n; i++ {
		D[i] = make([]float64, n)
		for j := 0; j < n; j++ {
			D[i][j] = math.Sqrt(float64((XY[i][0]-XY[j][0])*(XY[i][0]-XY[j][0]) + (XY[i][1]-XY[j][1])*(XY[i][1]-XY[j][1])))
		}
	}
	G := make([][]Edge, n)
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			G[i] = append(G[i], Edge{i, j, D[i][j]})
		}
	}

	ans := math.Inf(1)
	for s := 0; s < n; s++ {
		res := 0.0
		nonVisited := make(map[int]bool)
		for i := 0; i < n; i++ {
			nonVisited[i] = true
		}
		pi := newLinkedList() // 部分巡回路
		v := s
		pi.add(v)
		delete(nonVisited, v)
		que := priorityqueue.New[Edge](func(a, b Edge) int {
			if a.cost < b.cost {
				return -1
			} else if a.cost > b.cost {
				return 1
			}
			return 0
		}) // 挿入する辺の候補
		for _, e := range G[v] {
			que.Push(e)
		}
		for !que.Empty() {
			e := que.Pop()
			if pi.has(e.to) {
				continue
			}
			if pi.len == 1 {
				res += e.cost
				pi.add(e.to)
			} else {
				u := pi.head
				minCost := math.Inf(1)
				minV := -1
				for u.next != nil {
					cost := D[u.value][e.to] + D[e.to][u.next.value] - D[u.value][u.next.value]
					if cost < minCost {
						minCost = cost
						minV = u.value
					}
					u = u.next
				}
				res += minCost
				pi.insertAfter(minV, e.to)
			}
			delete(nonVisited, e.to)
			v = e.to
			for u := range nonVisited {
				que.Push(G[v][u])
			}
		}
		res += D[pi.tail.value][s]
		ans = math.Min(ans, res)
	}

	writeLine(ans)
}

func sum[T int | float64](arr ...T) T {
	sum := arr[0]
	for i := 1; i < len(arr); i++ {
		sum += arr[i]
	}
	return sum
}

func pow(x, n int) int {
	res := 1
	for n > 0 {
		if n&1 == 1 {
			res = res * x
		}
		x = x * x
		n >>= 1
	}
	return res
}

func lcm(a, b int) int {
	return a / gcd(a, b) * b
}

func gcd(a, b int) int {
	if b == 0 {
		return a
	}
	return gcd(b, a%b)
}

func abs[T int | float64](x T) T {
	if x < 0 {
		return -x
	}
	return x
}

func min[T int | float64](arr ...T) T {
	min := arr[0]
	for _, v := range arr {
		if v < min {
			min = v
		}
	}
	return min
}

func max[T int | float64](arr ...T) T {
	max := arr[0]
	for _, v := range arr {
		if v > max {
			max = v
		}
	}
	return max
}

func ceilDiv(a, b int) int {
	if b < 0 {
		return ceilDiv(-a, -b)
	}
	if a < 0 {
		return a / b
	}
	return (a + b - 1) / b
}

func floorDiv(a, b int) int {
	if b < 0 {
		return floorDiv(-a, -b)
	}
	return (a - positiveMod(a, b)) / b
}

func positiveMod(a, b int) int {
	return (a%b + b) % b
}

var _stdInReader = bufio.NewReader(os.Stdin)

func readLine() string {
	line, _ := _stdInReader.ReadString('\n')
	return strings.TrimSpace(line)
}

func readString() string {
	return readLine()
}

func readInt() int {
	strs := readString()
	num, _ := strconv.Atoi(strs)
	return num
}

func readLong() int64 {
	strs := readString()
	num, _ := strconv.ParseInt(strs, 10, 64)
	return num
}

func readStrings() []string {
	line := readLine()
	return strings.Split(line, " ")
}

func readInts() []int {
	strs := readStrings()
	arr := make([]int, len(strs))
	for i := 0; i < len(strs); i++ {
		arr[i], _ = strconv.Atoi(strs[i])
	}
	return arr
}

func readLongs() []int64 {
	strs := readStrings()
	arr := make([]int64, len(strs))
	for i := 0; i < len(strs); i++ {
		arr[i], _ = strconv.ParseInt(strs[i], 10, 64)
	}
	return arr
}

func readDoubles() []float64 {
	strs := readStrings()
	arr := make([]float64, len(strs))
	for i := 0; i < len(strs); i++ {
		arr[i], _ = strconv.ParseFloat(strs[i], 64)
	}
	return arr
}

func scanStringVariables(args ...*string) {
	n := len(args)
	scanned := 0
	for n > scanned {
		inputSlice := readStrings()
		m := len(inputSlice)
		if m == 0 || m > n-scanned {
			fmt.Print("Something wrong in scanStringVariables !!!")
			return
		}
		for i := 0; i < m; i++ {
			*args[i+scanned] = inputSlice[i]
		}
		scanned += m
	}
}

func scanIntVariables(args ...*int) {
	n := len(args)
	scanned := 0
	for n > scanned {
		inputSlice := readInts()
		m := len(inputSlice)
		if m == 0 || m > n-scanned {
			fmt.Printf("m %d n %d scanned %d. ", m, n, scanned)
			fmt.Print("Something wrong in scanIntVariables !!!")
			return
		}
		for i := 0; i < m; i++ {
			*args[i+scanned] = inputSlice[i]
		}
		scanned += m
	}
}

func scanLongVariables(args ...*int64) {
	n := len(args)
	scanned := 0
	for n > scanned {
		inputSlice := readLongs()
		m := len(inputSlice)
		if m == 0 || m > n-scanned {
			fmt.Print("Something wrong in scanIntVariables !!!")
			return
		}
		for i := 0; i < m; i++ {
			*args[i+scanned] = inputSlice[i]
		}
		scanned += m
	}
}

func write(arg ...interface{})                 { fmt.Print(arg...) }
func writeLine(arg ...interface{})             { fmt.Println(arg...) }
func writeFormat(f string, arg ...interface{}) { fmt.Printf(f, arg...) }

Submission Info

Submission Time
Task B23 - Traveling Salesman Problem
User hamao
Language Go (go 1.20.6)
Score 0
Code Size 6045 Byte
Status WA
Exec Time 1 ms
Memory 1832 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 0 / 1000
Status
AC × 2
AC × 14
WA × 2
Set Name Test Cases
Sample sample_01.txt, sample_02.txt
All in01.txt, in02.txt, in03.txt, in04.txt, in05.txt, in06.txt, in07.txt, in08.txt, in09.txt, in10.txt, in11.txt, in12.txt, in13.txt, in14.txt, sample_01.txt, sample_02.txt
Case Name Status Exec Time Memory
in01.txt AC 1 ms 1652 KiB
in02.txt AC 1 ms 1652 KiB
in03.txt AC 0 ms 1660 KiB
in04.txt AC 1 ms 1660 KiB
in05.txt AC 1 ms 1660 KiB
in06.txt AC 1 ms 1676 KiB
in07.txt AC 0 ms 1680 KiB
in08.txt AC 1 ms 1692 KiB
in09.txt AC 1 ms 1712 KiB
in10.txt WA 1 ms 1736 KiB
in11.txt AC 1 ms 1736 KiB
in12.txt WA 1 ms 1752 KiB
in13.txt AC 1 ms 1816 KiB
in14.txt AC 1 ms 1832 KiB
sample_01.txt AC 0 ms 1656 KiB
sample_02.txt AC 1 ms 1676 KiB