結果

問題 No.898 tri-βutree
ユーザー ccppjsrbccppjsrb
提出日時 2020-08-12 16:42:53
言語 Go
(1.22.1)
結果
AC  
実行時間 242 ms / 4,000 ms
コード長 3,374 bytes
コンパイル時間 14,498 ms
コンパイル使用メモリ 204,900 KB
実行使用メモリ 57,720 KB
最終ジャッジ日時 2023-08-08 16:52:43
合計ジャッジ時間 20,859 ms
ジャッジサーバーID
(参考情報)
judge13 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 133 ms
57,720 KB
testcase_01 AC 1 ms
4,380 KB
testcase_02 AC 2 ms
4,384 KB
testcase_03 AC 2 ms
4,380 KB
testcase_04 AC 2 ms
4,380 KB
testcase_05 AC 2 ms
4,380 KB
testcase_06 AC 1 ms
4,380 KB
testcase_07 AC 233 ms
43,424 KB
testcase_08 AC 231 ms
43,428 KB
testcase_09 AC 233 ms
43,428 KB
testcase_10 AC 226 ms
43,424 KB
testcase_11 AC 229 ms
43,424 KB
testcase_12 AC 231 ms
43,424 KB
testcase_13 AC 231 ms
43,424 KB
testcase_14 AC 229 ms
43,424 KB
testcase_15 AC 231 ms
43,424 KB
testcase_16 AC 235 ms
43,428 KB
testcase_17 AC 240 ms
43,428 KB
testcase_18 AC 237 ms
43,428 KB
testcase_19 AC 239 ms
43,424 KB
testcase_20 AC 242 ms
43,424 KB
testcase_21 AC 238 ms
43,424 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package main

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

func configure(scanner *bufio.Scanner) {
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1000005), 1000005)
}
func getNextString(scanner *bufio.Scanner) string {
	scanned := scanner.Scan()
	if !scanned {
		panic("scan failed")
	}
	return scanner.Text()
}
func getNextInt(scanner *bufio.Scanner) int {
	i, _ := strconv.Atoi(getNextString(scanner))
	return i
}
func getNextInt64(scanner *bufio.Scanner) int64 {
	i, _ := strconv.ParseInt(getNextString(scanner), 10, 64)
	return i
}
func getNextFloat64(scanner *bufio.Scanner) float64 {
	i, _ := strconv.ParseFloat(getNextString(scanner), 64)
	return i
}
func main() {
	fp := os.Stdin
	wfp := os.Stdout
	extra := 0
	if os.Getenv("I") == "IronMan" {
		fp, _ = os.Open(os.Getenv("END_GAME"))
		extra = 100
	}
	scanner := bufio.NewScanner(fp)
	configure(scanner)
	writer := bufio.NewWriter(wfp)
	defer func() {
		r := recover()
		if r != nil {
			fmt.Fprintln(writer, r)
		}
		writer.Flush()
	}()
	solve(scanner, writer)
	for i := 0; i < extra; i++ {
		fmt.Fprintln(writer, "-----------------------------------")
		solve(scanner, writer)
	}
}
func solve(scanner *bufio.Scanner, writer *bufio.Writer) {
	n := getNextInt(scanner)
	g := newGraph(n)
	for i := 0; i < n; i++ {
		for j := 0; j < 32; j++ {
			g.v[i].p[j] = -1
		}
	}
	for i := 0; i < n-1; i++ {
		v := getNextInt(scanner)
		u := getNextInt(scanner)
		w := getNextInt64(scanner)
		g.appendEdge(v, u, i, w)
		g.appendEdge(u, v, i, w)
	}
	g.dfs(0, -1)
	g.setuplca()
	q := getNextInt(scanner)
	for i := 0; i < q; i++ {
		x := getNextInt(scanner)
		y := getNextInt(scanner)
		z := getNextInt(scanner)
		v1 := g.lca(x, y)
		v2 := g.lca(y, z)
		v3 := g.lca(x, z)
		if g.v[v1].d > g.v[v2].d {
			if g.v[v1].d < g.v[v3].d {
				fmt.Fprintln(writer, g.weight(x, z, v3)+g.weight(y, v3, g.lca(y, v3)))
				continue
			}
			fmt.Fprintln(writer, g.weight(x, y, v1)+g.weight(z, v1, g.lca(z, v1)))
			continue
		}
		if g.v[v2].d > g.v[v3].d {
			fmt.Fprintln(writer, g.weight(y, z, v2)+g.weight(x, v2, g.lca(x, v2)))
			continue
		}
		fmt.Fprintln(writer, g.weight(x, z, v3)+g.weight(y, v3, g.lca(y, v3)))
	}
}

type vertex struct {
	d int
	p [32]int
	w int64
}
type edge struct {
	to, id int
	w      int64
}
type graph struct {
	v []vertex
	e [][]edge
}

func newGraph(n int) graph {
	return graph{
		v: make([]vertex, n),
		e: make([][]edge, n),
	}
}
func (g *graph) appendEdge(from, to, id int, w int64) {
	g.e[from] = append(g.e[from], edge{
		to: to,
		id: id,
		w:  w,
	})
}

func (g *graph) dfs(i, p int) {
	for _, e := range g.e[i] {
		if e.to == p {
			continue
		}
		g.v[e.to].p[0] = i
		g.v[e.to].d = g.v[i].d + 1
		g.v[e.to].w = g.v[i].w + e.w
		g.dfs(e.to, i)
	}
}
func (g *graph) setuplca() {
	for i := 1; i < 32; i++ {
		for j := 0; j < len(g.v); j++ {
			if g.v[j].p[i-1] == -1 {
				continue
			}
			g.v[j].p[i] = g.v[g.v[j].p[i-1]].p[i-1]
		}
	}
}
func (g *graph) lca(x, y int) int {
	if g.v[x].d > g.v[y].d {
		x, y = y, x
	}
	d := g.v[y].d - g.v[x].d
	for i := 31; i >= 0; i-- {
		if d>>uint(i)&1 == 0 {
			continue
		}
		y = g.v[y].p[i]
	}
	if x == y {
		return x
	}
	for i := 31; i >= 0; i-- {
		if g.v[x].p[i] == g.v[y].p[i] {
			continue
		}
		x = g.v[x].p[i]
		y = g.v[y].p[i]
	}
	return g.v[x].p[0]
}
func (g *graph) weight(x, y, v int) int64 {
	return g.v[x].w + g.v[y].w - g.v[v].w<<1
}
0