結果

問題 No.416 旅行会社
ユーザー fmhrfmhr
提出日時 2016-08-30 08:12:25
言語 Go
(1.22.1)
結果
AC  
実行時間 408 ms / 4,000 ms
コード長 3,480 bytes
コンパイル時間 11,591 ms
コンパイル使用メモリ 226,844 KB
実行使用メモリ 34,560 KB
最終ジャッジ日時 2024-05-08 15:20:02
合計ジャッジ時間 16,974 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 213 ms
16,128 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 1 ms
5,376 KB
testcase_04 AC 1 ms
5,376 KB
testcase_05 AC 1 ms
5,376 KB
testcase_06 AC 1 ms
5,376 KB
testcase_07 AC 2 ms
5,376 KB
testcase_08 AC 5 ms
5,376 KB
testcase_09 AC 26 ms
5,376 KB
testcase_10 AC 222 ms
16,640 KB
testcase_11 AC 246 ms
16,640 KB
testcase_12 AC 244 ms
16,640 KB
testcase_13 AC 229 ms
16,256 KB
testcase_14 AC 404 ms
34,560 KB
testcase_15 AC 387 ms
33,920 KB
testcase_16 AC 360 ms
34,048 KB
testcase_17 AC 405 ms
34,560 KB
testcase_18 AC 408 ms
34,048 KB
testcase_19 AC 319 ms
26,624 KB
testcase_20 AC 325 ms
27,136 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"strconv"
)

const inf int = 1 << 25

func main() {
	sc.Split(bufio.ScanWords)
	// indexと島を合わせるために孤立した島0を加えておく
	n := nextInt() + 1
	m := nextInt()
	q := nextInt()
	bridge := make([]nodes, m)
	crashed := make(map[int]int)
	for i := 0; i < m; i++ {
		bridge[i].a = nextInt()
		bridge[i].b = nextInt()
		crashed[bridge[i].a*1000000+bridge[i].b] = inf
	}
	crash := make([]nodes, q)
	for i := 0; i < q; i++ {
		crash[i].a = nextInt()
		crash[i].b = nextInt()
		crashed[crash[i].a*1000000+crash[i].b] = i + 1
	}

	// グラフ
	g := newGraph(n)
	for i := 0; i < m; i++ {
		a := bridge[i].a
		b := bridge[i].b
		cost := crashed[a*1000000+b]
		g[a] = append(g[a], Edge{to: b, time: cost})
		g[b] = append(g[b], Edge{to: a, time: cost})
	}
	// 改変ダイクストラ
	d := g.dijkstar(n, 1)

	// 最後までつながっている島: -1
	// 最初からつながっている島: 0
	for i := 2; i < n; i++ {
		switch d[i] {
		case inf:
			fmt.Println("-1")
		case -1:
			fmt.Println("0")
		default:
			fmt.Println(d[i])
		}
	}
}

type nodes struct {
	a, b int
}

type Edge struct {
	to   int
	time int
}
type Graph [][]Edge

func newGraph(n int) Graph {
	g := make(Graph, n)
	for i := range g {
		g[i] = make([]Edge, 0)
	}
	return g
}

func (g *Graph) dijkstar(n, s int) []int {
	d := make([]int, n) // 頂点sからの最短距離
	for i := range d {
		d[i] = -1
	}
	// 優先度(最後につながっているイベントタイム)が大きい島からとりだす
	que := make(PriorityQueue, 0)
	heap.Init(&que)
	d[s] = inf
	heap.Push(&que, &Item{node: s, time: inf})
	for que.Len() > 0 {
		p := heap.Pop(&que).(*Item)
		v := p.node
		// 生存時間が島より短い橋は無視する
		if d[v] > p.time {
			continue
		}
		for i := 0; i < len((*g)[v]); i++ {
			// 先の島から伸びてる橋を走査
			e := (*g)[v][i]
			t := min(d[v], e.time) // 新しい経路の生存時間
			if d[e.to] < t {
				d[e.to] = t
				heap.Push(&que, &Item{time: d[e.to], node: e.to})
			}
		}
	}
	return d
}

// https://golang.org/pkg/container/heap/
// An Item is something we manage in a priority queue.
type Item struct {
	node int // The value of the item; arbitrary.
	time int // The priority of the item in the queue.
	// The index is needed by update and is maintained by the heap.Interface methods.
	index int // The index of the item in the heap.
}

type PriorityQueue []*Item

func (pq PriorityQueue) Len() int { return len(pq) }

func (pq PriorityQueue) Less(i, j int) bool {
	// We want Pop to give us the highest, not lowest, priority so we use greater than here.
	return pq[i].time > pq[j].time
}

func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}

func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Item)
	item.index = n
	*pq = append(*pq, item)
}

func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	item.index = -1 // for safety
	*pq = old[0 : n-1]
	return item
}

func (pq *PriorityQueue) update(item *Item, value int, priority int) {
	item.node = value
	item.time = priority
	heap.Fix(pq, item.index)
}

var sc = bufio.NewScanner(os.Stdin)

func nextLine() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	i, _ := strconv.Atoi(nextLine())
	return i
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
0