← Home
```go
package main

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

const INF = int64(1 << 60)

type Edge struct {
	to int
	w  int64
	id int
}

type Node struct {
	v int
	d int64
}

type MinHeap []Node

func (h MinHeap) Len() int           { return len(h) }
func (h MinHeap) Less(i, j int) bool { return h[i].d < h[j].d }
func (h MinHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x interface{}) {
	*h = append(*h, x.(Node))
}
func (h *MinHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[:n-1]
	return x
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	readInt := func() int {
		b, _ := reader.ReadByte()
		for b < '0' || b > '9' {
			b, _ = reader.ReadByte()
		}
		val := 0
		for b >= '0' && b <= '9' {
			val = val*10 + int(b-'0')
			b, _ = reader.ReadByte()
		}
		return val
	}
	readInt64 := func() int64 {
		b, _ := reader.ReadByte()
		for b < '0' || b > '9' {
			b, _ = reader.ReadByte()
		}
		var val int64 = 0
		for b >= '0' && b <= '9' {
			val = val*10 + int64(b-'0')
			b, _ = reader.ReadByte()
		}
		return val
	}

	n := readInt()
	m := readInt()

	adj := make([][]Edge, n+1)
	type E struct {
		u, v int
		w    int64
	}
	edges := make([]E, m+1)

	for i := 1; i <= m; i++ {
		u := readInt()
		v := readInt()
		w := readInt64()
		edges[i] = E{u, v, w}
		adj[u] = append(adj[u], Edge{to: v, w: w, id: i})
		adj[v] = append(adj[v], Edge{to: u, w: w, id: i})
	}

	src := readInt()

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

	h := &MinHeap{}
	heap.Init(h)
	heap.Push(h, Node{v: src, d: 0})

	for h.Len() > 0 {
		cur := heap.Pop(h).(Node)
		if cur.d != dist[cur.v] {
			continue
		}
		for _, e := range adj[cur.v] {
			if dist[cur.v]+e.w < dist[e.to] {
				dist[e.to] = dist[cur.v] + e.w
				heap.Push(h, Node{v: e.to, d: dist[e.to]})
			}
		}
	}

	bestEdge := make([]int, n+1)
	bestWeight := make([]int64, n+1)
	for i := 1; i <= n; i++ {
		bestWeight[i] = INF
	}
	bestWeight[src] = 0

	for i := 1; i <= m; i++ {
		u := edges[i].u
		v := edges[i].v
		w := edges[i].w
		if dist[u]+w == dist[v] && w < bestWeight[v] {
			bestWeight[v] = w
			bestEdge[v] = i
		}
		if dist[v]+w == dist[u] && w < bestWeight[u] {
			bestWeight[u] = w
			bestEdge[u] = i
		}
	}

	var total int64
	res := make([]int, 0, n-1)
	for i := 1; i <= n; i++ {
		if i != src {
			total += bestWeight[i]
			res = append(res, bestEdge[i])
		}
	}

	out.WriteString(strconv.FormatInt(total, 10))
	out.WriteByte('\n')
	for i, id := range res {
		if i > 0 {
			out.WriteByte(' ')
		}
		out.WriteString(strconv.Itoa(id))
	}
	out.WriteByte('\n')
}
```