Problem:
JOI 公園 (JOI Park)

20XX 年に IOI 国で行われるオリンピックに備え，IOI 国にある JOI 公園を整備することになった．JOI公園には N 個の広場があり，広場には 1 から N の番号がついている．広場を繋ぐ M 本の道があり，道には 1 から M の番号がついている．道 i (1 ≤ i ≤ M) は広場 Ai と広場 Bi を双方向に繋いでおり，長さは Di である．どの広場からどの広場へもいくつかの道を辿って行くことができる．

整備計画では，まず，0 以上の整数 X を選び，広場 1 からの距離が X 以下であるような広場 (広場 1 を含む) どうしをすべて相互に地下道で結ぶ．ただし，広場 i と広場 j の距離とは，広場 i から広場 j に行くときに通る道の長さの和の最小値である．整備計画では地下道の整備コストに関する整数 C が定まっている．地下道の整備にかかるコストは C × X である．

次に，地下道で結ばれた広場どうしを結ぶ道をすべて撤去する．道の撤去にコストはかからない．最後に，撤去されずに残った道をすべて補修する．長さ d の道を補修するためにかかるコストは d である．整備計画実施前の JOI 公園には地下道はない．JOI 公園の整備にかかるコストの和の最小値を求めよ．

課題

JOI 公園の広場の情報と，地下道の整備コストに関する整数が与えられたとき，JOI 公園の整備にかかる
コストの和の最小値を求めるプログラムを作成せよ．

入力

標準入力から以下のデータを読み込め．

1 行目には，整数 N, M,C が空白を区切りとして書かれている．これは，広場が N 個，道が M 本あり，地下道の整備コストに関する整数が C であることを表す．

続く M 行のうちの i 行目 (1 ≤ i ≤ M) には，整数 Ai, Bi, Di が空白を区切りとして書かれている．これは，道 i が広場 Ai と広場 Bi を繋ぎ，長さが Di であることを表す．

出力

標準出力に，JOI 公園の整備にかかるコストの和の最小値を表す整数を 1 行で出力せよ．

制限

すべての入力データは以下の条件を満たす．

2 ≤ N ≤ 100 000．

1 ≤ M ≤ 200 000．

1 ≤ C ≤ 100 000．

1 ≤ Ai ≤ N (1 ≤ i ≤ M)．

1 ≤ Bi ≤ N (1 ≤ i ≤ M)．

Ai ≠ Bi (1 ≤ i ≤ M)．

(Ai, Bi) ≠ (Aj, Bj) および (Ai, Bi) ≠ (Bj, Aj) (1 ≤ i < j ≤ M)．

1 ≤ Di ≤ 100 000 (1 ≤ i ≤ M)．

与えられる入力データにおいては，どの広場からどの広場へもいくつかの道を辿ることにより行けることが保証されている．

入出力例

入力例 1

5 5 2
2 3 1
3 1 2
2 4 3
1 2 4
2 5 5

出力例 1

14

この入力例では，X = 3 として，広場 1 からの距離が 3 以下であるような広場 (広場 1, 広場 2, 広場 3) どうしをすべて相互に地下道で結んだとき，整備にかかるコストの和は 2 × 3 + 3 + 5 = 14 となる．これが最小値である．

入力例 2

5 4 10
1 2 3
2 3 4
3 4 3
4 5 5

出力例 2

15

この入力例では，X = 0 のとき整備にかかるコストの和が最小になる．

入力例 3

6 5 2
1 2 2
1 3 4
1 4 3
1 5 1
1 6 5

出力例 3

10

この入力例では，X = 5 としてすべての広場を相互に地下道で結んだとき，整備にかかるコストの和が最小になる．

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in Ruby (judge verdict: Runtime Error)

module Graph
	require 'set'

	def add_node(label = nil)
		Node.new(label)
	end

	def add_edge(u, v, label = nil)
		e = Edge.new(u, v, label)
		u.outgoings << e
		v.incomings << e
		e
	end
	
	def del_edge(e)
		u, v = e.from, e.to
		u.outgoings.delete(e)
		v.incomings.delete(e)
		e
	end

	class Node
		def initialize(label)
			@label = label
			@outgoings = Set.new
			@incomings = Set.new
		end

		def to_nodes
			@outgoings.map(&:to)
		end

		def from_nodes
			@incomings.map(&:from)
		end
		
		attr_accessor :incomings, :outgoings
		attr_reader :label
	end

	class Edge
		def initialize(u, v, label = nil)
			@from = u	
			@to = v
			@label = label
		end
		attr_reader :from, :to, :label
	end

	def get_path_bfs(s, t)
		path_edge = {}
		reached = Set[s]
		queue = [s]
		while !queue.empty? 
			u = queue.shift
			u.outgoings.each{|e|
				v = e.to
				next if reached.include?(v)	
				reached << v
				queue << v
				path_edge[v] = e

				if v == t
					path = []
					while e = path_edge[v]
						path.unshift e
						v = e.from
					end
					return path
				end
			}
		end	
		return nil
	end

	def get_path_dfs(s, t, reached = Set.new)
		reached << s	
		s.outgoings.each{|e|
			v = e.to
			next if reached.include?(v)
			return [e] if v == t
			
			path = get_path_dfs(v, t, reached) 
			return [e] + path if path
		}
		nil
	end

	def layers_from(start)
		reached = Set[*start]
		layers = [start]

		loop {
			layers << []
			layers[-2].each{|u|
				u.to_nodes.each{|v|
					next if reached.include?(v)
					reached << v
					layers[-1] << v
				}
			}	

			if layers[-1].empty?
				layers.pop
				return layers
			end
		}
	end

	def reachable_from(s, reached = Set.new, root = true)
		reached << s	
		s.outgoings.each{|e|
			v = e.to
			next if reached.include?(v)
			reachable_from(v, reached, false) 
		}
		root ? reached : nil
	end
end

class Heap
	require 'forwardable'
	extend Forwardable

	def initialize
		@array = []
		@index = {}
	end

	def add(obj, key)
		@array << [obj, key]
		@index[obj] = @array.size - 1
		lift_up(@array.size - 1)
	end

	def swap(i, j)
		u = @array[i]
		v = @array[j]
		@index[u[0]], @index[v[0]] = j, i
		@array[i], @array[j] = v, u
	end

	def lift_up(i)
		return if i == 0
		j = (i - 1) / 2
		if @array[i][1] < @array[j][1]
			swap(i, j)
			lift_up(j)
		end
	end

	def del_min
		raise "heap is empty!" if empty?
		min = @array[0]
		if size > 1
			swap(0, @array.size-1)
			@array.pop
			lift_down(0)
		else
			@array.pop
		end
		@index.delete(min[0])
		min
	end

	def inc_key(obj, diff)
		i = @index[obj]
		@array[i][1] += diff
		lift_down(i)
	end

	def dec_key(obj, diff)
		i = @index[obj]
		@array[i][1] -= diff
		lift_up(i)
	end

	def update_key(obj, new_key)
		i = @index[obj]
		return unless i
		return if @array[i][1] <= new_key
		@array[i][1] = new_key
		lift_up(i)
	end

	def min_obj
		@array[0][0]
	end

	def min_key
		@array[0][1]
	end

	def lift_down(i)
		j = 2 * i + 1
		k = j + 1
		if k >= size
			return if j >= size
			if @array[i][1] > @array[j][1]
				swap(i, j)
				lift_down(j)
			end
		else
			l = (@array[j][1] < @array[k][1] ? j : k)
			if @array[i][1] > @array[l][1]
				swap(i, l)
				lift_down(l)
			end
		end
	end

	def_delegators :@array, :empty?, :size
end
extend Graph

n, m, c = gets.split.map(&:to_i)

nodes = [add_node(:dummy)] + (1..n).map{ add_node }
edges = {}

m.times {
	i, j, w = gets.split.map(&:to_i)
	u, v = nodes[i], nodes[j]
	e1 = add_edge(u, v, w)
	e2 = add_edge(v, u, w)
	edges[Set[u, v]] = [e1, e2]
}

h = Heap.new
nodes.each{|v|
	h.add(v, Float::INFINITY)
}
h.update_key(nodes[1], 0)

require "set"
dist = {}
reached = Set[nodes[1]]

until h.size == 1
	u, key = h.del_min
	dist[u] = key
	u.outgoings.each{|e|
		v = e.to
		h.update_key(v, dist[u] + e.label)
		reached << v unless reached.include?(v)
	}
end

nodes.shift
nodes.sort_by!{|v| dist[v]}
nearby_nodes = []

min = Float::INFINITY
x = 0
repair_cost = nodes.map{|v| v.outgoings.map{|e| e.label}.inject(:+)}.inject(:+) / 2
loop {
	while !nodes.empty? && dist[nodes[0]] == x
		u = nodes.shift
		nearby_nodes.each{|v|
			e1, e2 = edges[Set[u, v]]
			next unless e1
			repair_cost -= e1.label
			del_edge(e1)
			del_edge(e2)
		}
		nearby_nodes << u
	end

	create_cost = c * x
	total = create_cost + repair_cost

	min = total if total < min
	
	break if nodes.empty?	

	x = dist[nodes[0]]
}

p min