Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

const INF = 0x7FFFFFFF

func main() {
	for scanner.Scan() {
		n, _ := strconv.Atoi(scanner.Text())
		if n == 0 {
			break
		}
		having := map[string]Entry{}
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf := strings.Split(scanner.Text(), " ")
			name := buf[0]
			price, _ := strconv.Atoi(buf[1])
			having[name] = Entry{price, []string{}}
		}
		scanner.Scan()
		m, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < m; i++ {
			scanner.Scan()
			buf_ := strings.Split(scanner.Text(), " ")
			name_, price_ := buf_[0], INF
			if _, ok := having[name_]; ok {
				price_ = having[name_].price
			}
			having[name_] = Entry{price_, buf_[2:]}
		}
		scanner.Scan()
		fmt.Println(calculation(scanner.Text(), having))
	}
}

type Entry struct {
	price int
	elements []string
}

// メモ再帰的
func calculation(target string, having map[string]Entry) int {
	ans := INF
	if len(having[target].elements) > 0 {
		ans = 0
		for _, item := range having[target].elements {
			ans += calculation(item, having)
		}
	}
	return min(ans, having[target].price)
}

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

Python: # Aizu Problem 0201: Wrought Gold Master
#
import sys, math, os

# read input:
PYDEV = os.environ.get('PYDEV')
if PYDEV=="True":
    sys.stdin = open("sample-input.txt", "rt")

class DirectedGraph():
    def __init__(self):
        self.edges = {}

    def AddNode(self, node):
        if node not in self.edges:
            self.edges[node] = []

    def GetNodes(self):
        return list(self.edges.keys())

    def GetEdges(self):
        return self.edges

    def AddEdge(self, node1, node2):
        if node1 not in self.GetNodes():
            self.AddNode(node1)
        if node2 not in self.edges[node1]:
            self.edges[node1].append(node2)

    def RemoveEdge(self, node1, node2):
        if node1 not in self.edges or node2 not in self.edges[node1]:
            print("ERROR: can't remove edge", node1, "->", node2)
            print(self.edges)
            return
        self.edges[node1].remove(node2)

    def OutDegree(self, node):
        return len(self.edges[node])

    def InDegree(self, node):
        deg = 0
        for node2 in self.GetNodes():
            if node in self.GetNeighbors(node2):
                deg += 1
        return deg

    def GetNeighbors(self, node):
        return self.edges.get(node, [])
            
    def GetPath(self, source, target):
        # find path by BFS:
        predecessor = {node: -1 for node in self.GetNodes()}
        predecessor[source] = 0
        visited = {node: False for node in self.GetNodes()}
        queue = [source]
        while len(queue) > 0:
            current = queue.pop(0)
            visited[current] = True
            for neighbor in self.GetNeighbors(current):
                if not visited[neighbor] and neighbor not in queue:
                    queue.append(neighbor)
                    predecessor[neighbor] = current
                if neighbor == target:
                    queue = []
                    break
        # build path from predecessor info:
        if predecessor[target] == -1:
            return []
        path = [target]
        while path[0] != source:
            path = [predecessor[path[0]]] + path[:]
        return path

    def TopologicalSort(self):
        # determine topological sorting of graph by Kahn's algorithm;
        # edges are removed by this algorithm
        L = []
        S = [node for node in self.GetNodes() if self.InDegree(node) == 0]
        while len(S) > 0:
            n = S.pop(0)
            L.append(n)
            for m in self.GetNeighbors(n)[:]:
                self.RemoveEdge(n, m)
                if self.InDegree(m) == 0:
                    S.append(m)
        for node in self.GetNodes():
            if self.edges[node] != []:
                print("ERROR: graph has cycle!", self.edges)
                return
        return L


while True:
    n = int(input())
    if n == 0:
        break
    G = DirectedGraph()
    prices = {}
    for _ in range(n):
        item, price = input().split()
        prices[item] = int(price)
    m = int(input())
    recipes = {}
    for _ in range(m):
        inp = input().split()
        item = inp[0]
        recipes[item] = inp[2:]
        for source in inp[2:]:
            G.AddEdge(item, source)
    target = input().strip()
    for item in G.TopologicalSort()[::-1]:
        if item in recipes:
            prices[item] = min(prices[item], sum([prices[source] for source in recipes[item]]))
    print(prices[target])

Python: def price(target, item, recipe):
    ret = []
    
    if target in recipe:
        ret.append(sum(price(r,item, recipe) for r in recipe[target]))
    if target in item:
        ret.append(item[target])
    if len(ret) == 0:
        return 0

    return min(ret)

import sys
f = sys.stdin

while True:
    n = int(f.readline())
    if n == 0:
        break
    item = [f.readline().split() for _ in range(n)]
    item = {name:int(price) for name, price in item}
    recipe = [f.readline().strip().split() for _ in range(int(f.readline()))]
    recipe = {r[0]:r[2:] for r in recipe}
    print(price(f.readline().strip(), item, recipe))

Python: while True:

    item_list = {}

    n = int(input())
    if n == 0: break
    for _ in range(n):
        item, cost = input().split()
        item_list[item] = int(cost)

    recipe_list = {}

    k = int(input())
    for _ in range(k):
        material = input().split()
        items = material[2:]
        recipe_list[material[0]] = items

    t = input()

    item_cost = item_list[t]
    if k:
        recipe = recipe_list[t]

        recipe_cost = 0
        for item in recipe:
            if item in recipe_list:
                recipe_cost += sum([item_list[x] for x in recipe_list[item]])
            else:
                recipe_cost += item_list[item]
    
        if recipe_cost < item_cost:
            print(recipe_cost)
        else:
            print(item_cost)
    else:
        print(item_cost)

Python: # from pprint import pprint as pprint
import copy

def findrecipe(rec,ite,obj):
    # pprint(rec)
    # print("obj: ",obj)
    # print("=-")
    try:
        mat = rec[obj]
        rec2 = copy.copy(rec)
        del rec2[obj]
        price = min(ite[obj],sum([findrecipe(rec2,ite,m) for m in mat]))
        # print(price,obj)
        return price
    except:
        return ite[obj]

while(True):
    try:
        item = {}
        n = int(input())
        for _ in range(n):
            s,p = input().split()
            p = int(p)
            item[s] = p
        recipe = {}
        m = int(input())
        for _ in range(m):
            o,k,qs = input().split(" ",2)
            recipe[o] = qs.split()

        t = input()
        print(findrecipe(recipe,item,t))
    except:
        break

Python: # AOJ 0201: Wrought Gold Master
# Python3 2018.6.26 bal4u

INF = 0x7fffffff

def calc(t):
	ans = INF
	if len(mono[t][1]) > 0:
		ans = 0
		for i in mono[t][1]: ans += calc(i)
	return min(ans, mono[t][0])

while True:
	n = int(input())
	if n == 0: break
	mono = {}
	for i in range(n):
		s, p = input().split()
		mono[s] = (int(p), [])
	m = int(input())
	for i in range(m):
		a = input().split()
		s, p = a[0], INF
		if s in mono: p = mono[s][0]
		mono[s] = (p, a[2:])
	print(calc(input()))