Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem C:
TransferTrain

うなぎは電車に乗るのが好きである. いま，うなぎは駅 A から駅 B へ電車を使って行こうとしている. うなぎは急いでいるので, 最短時間の経路を選ぶことにした. ただし，うなぎは乗り換えが苦手なので, 最短時間の経路が複数ある場合は最も乗り換え回数の少ない経路を選ぶことにした.

$N$ 本の路線がある. $i$ 本目の路線は $a_i$ 個の駅を通っている. $i$ 本目の路線の通る駅名は通る順に $s_{i,0}, ... , s_{i,a_i -1}$ であり, 駅間の所要時間は $t_{i,0}, ..., t_{i,a_i - 2}$ である. 電車は路線上を上下方向に走っており, 入力で与えられた逆順に乗ることもできる. 複数の路線の同じ駅名は同じ駅を表しており，乗り換えをすることが出来る. 乗り換えには駅や路線によらず $T$ 分かかる.

一本の路線が同じ駅を複数回通ることもある．もし同じ路線，同じ駅の，路線内で異なる位置の駅に移動したい場合は乗り換えをする必要がある. たとえば, C - D - E - F - D - G という路線を使って C から G まで行く場合, 始点から終点まで一本の電車で行くことも，D 駅で乗り換えて C - D, D - G と乗ることもできる.

うなぎが駅 A から駅 B へ行くのにかかる時間と乗り換え回数を求めよ. 電車はとても頻繁に来るので待ち時間は無視してよい.

Constraints

$N$ will be between 1 and 50,000, inclusive.

$T$ will be an integer between 1 and 1,000, inclusive.

At least one train stops at A.

At least one train stops at B.

A and B will be distinct.

$a_i$ will be bigger than or equal to 2.

$a_1 + ... + a_N$ will be between 2 and 100,000, inclusive.

$s_{i,j}$ will contain between 1 and 10 characters, inclusive.

Each character in $s_{i,j}$ will be a letter ('A'-'Z', 'a'-'z').

$t_{i,j}$ will be an integer between 1 and 1,000, inclusive.

Input

入力は以下の形式で与えられる:

$N$ $T$

$A$ $B$

$a_1$

$s_{1,1}$ ... $s_{1,a_1}$

$t_{1,1}$ ... $t_{1,a_1 -1}$

...

$a_N$

$s_{N,1}$ ... $s_{N,a_N}$

$t_{N,1}$ ... $t_{N,a_N-1}$

Output

うなぎが駅 A から駅 B へ行くのにかかる時間と乗り換え回数を空白で区切って1 行に出力せよ.

Sample Input 1

2 10
Warsaw Petersburg
3
Kiev Moscow Petersburg
150 120
3
Moscow Minsk Warsaw
100 150

Sample Output 1

380 1

Sample Input 2

2 10
Warsaw Petersburg
3
Kiev Moscow Petersburg
150 120
2
Minsk Warsaw
150

Sample Output 2

-1

Solution in Ruby (judge verdict: Memory Limit Exceeded)

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]) < 0
			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 (new_key <=> @array[i][1]) >= 0
		@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]) > 0
				swap(i, j)
				lift_down(j)
			end
		else
			l = ((@array[j][1] <=> @array[k][1]) < 0 ? j : k)
			if (@array[i][1] <=> @array[l][1]) > 0
				swap(i, l)
				lift_down(l)
			end
		end
	end

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

module Graphical
	require 'set'

	def dijkstra(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		h = Heap.new
		reached = Set[*start.to_a]
		start.each{|s| h.add(s, 0)}

		dist = {}
		until h.empty?
			u, key = h.del_min
			return key if block_given? && yield(u, key)
			dist[u] = key
			each_out_connection_of(u){|v, l|
				d = dist[u] + l
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		block_given? ? nil : dist
	end

	def bidir_dijkstra(s, t)
		f_dist = {}
		b_dist = {}

		f_heap = Heap.new
		b_heap = Heap.new

		f_heap.add(s, 0)
		b_heap.add(t, 0)

		f_reached = Set[s]
		b_reached = Set[t]

		f_current_dist = b_current_dist = 0
		best = Float::INFINITY

		loop {
			if !f_heap.empty?
				u, key = f_heap.del_min
				f_dist[u] = key
				f_current_dist = key
				each_out_connection_of(u){|v, l|
					d = f_dist[u] + l
					if b_dist[v]
						path_len = d + b_dist[v]
						best = path_len if path_len < best
					end
					if f_reached.include?(v)
						f_heap.update_key(v, d)
					else
						f_heap.add(v, d)
						f_reached << v
					end
				}
			end

			if !b_heap.empty?
				u, key = b_heap.del_min
				b_dist[u] = key
				b_current_dist = key
				each_in_connection_of(u){|v, l|
					d = b_dist[u] + l
					if f_dist[v]
						path_len = d + f_dist[v]
						best = path_len if path_len < best
					end
					if b_reached.include?(v)
						b_heap.update_key(v, d)
					else
						b_heap.add(v, d)
						b_reached << v
					end
				}
			end

			return best if f_current_dist + b_current_dist >= best
			return nil if f_heap.empty? && b_heap.empty?
		}
	end


	#make_variations :bidir_dijkstra


end

class Graph
	include Graphical

	def initialize(*options)
		@options = Set[*options]
	end

	def add_node()
		Node.new()
	end

	def add_edge(u, v, property = {})
		e = Edge.new(u, v, property)
		u.add_edge(e)
		v.add_edge(e)
		e
	end
	
	def del_edge(e)
		u, v = e.opposite.keys
		u.del_edge(e)
		v.del_edge(e)
		e
	end

	class Node
		def initialize()
			@edges = Set.new
		end

		def add_edge(e)
			@edges << e
		end

		def each_edge
			@edges.each{|e| 
				yield e
			}
		end
	end

	class Edge
		def initialize(u, v, l)
			@opposite = {u => v, v => u}
			@length = l
		end
		attr_reader :opposite, :length

		def to_s
			@property[:name] || super
		end
	end

	def each_out_connection_of(u)
		u.each_edge{|e|
			yield(e.opposite[u], e.length)
		}
	end

	alias :each_in_connection_of :each_out_connection_of
end

n, t = gets.split.map &:to_i
a, b = gets.chomp.split
g = Graph.new
nodes = {}
M = 10**10

n.times {
	m = gets.to_i
	line = gets.chomp.split.map{|name|
		u = g.add_node()
		nodes[name] ||= Set.new
		nodes[name].each{|v| g.add_edge(u, v, t * M + 1)}
		nodes[name] << u
		u
	}
	lens = gets.split.map &:to_i
	line.each_cons(2){|u, v|
		g.add_edge(u, v, lens.shift * M)
	}
}

d = g.dijkstra(nodes[a]){|v| nodes[b].include?(v)}
if d
	puts [d/M, d%M] * " "
else
	puts -1
end