Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"log"
	"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))
		log.Printf("%+v\n", 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
}

C++: #include<iostream>
#include<vector>
#include<string>
#include <map>
#include<algorithm>
using namespace std;
int search(string, pair<string, int>*, pair<string, vector<string> >*);
int n;
int m,si;
int main()
{
	
	while (true){
		pair<string, int>p[101];
		pair<string, vector<string> >chan[101];
		cin >> n;
		if (n == 0){
			break;
		}
		for (int i = 0; i < n; i++){
			cin >> p[i].first >> p[i].second;
		}

		cin >> m;
		for (int i = 0; i < m; i++){
			cin >> chan[i].first >> si;
			for (int i2 = 0; i2 < si; i2++){
				string s;
				cin >> s;
				chan[i].second.push_back(s);
			}
		}
		string s;
		cin >> s;
		int ans = search(s,p,chan);
		cout << ans << endl;
	}
}
int search(string s, pair<string, int>*p, pair<string, vector<string> >*chan){
	int num = 0;
	bool flag = true;
	for (int i = 0; i < m; i++){
		if (chan[i].first == s){
			flag = false;
			for (int i2 = 0; i2 < chan[i].second.size(); i2++){
				num += search(chan[i].second[i2],p,chan);
			}
			break;
		}
	}
	if (!flag){
		int k;
		for (int i = 0; i < n; i++){
			if (p[i].first == s){
				num=min(p[i].second,num);
				break;
			}
		}
	}
	if (flag){
		for (int i = 0; i < n; i++){
			if (p[i].first == s){
				num += p[i].second;
				break;
			}
		}
	}
	return num;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <map>

using namespace std;
typedef pair<string, int> P;

void solve()
{
	int n;
	while(cin >> n, n)
	{
		map<string, int> Map;
		for(int i = 0; i < n; ++i)
		{
			string s;
			int t;
			cin >> s >> t;
			Map[s] = t;
		}
		int m;
		cin >> m;
		vector<string> item(m);
		vector<int> Vec(m);
		vector< vector<string> > str(m);
		for(int i = 0; i < m; ++i)
		{
			cin >> item[i] >> Vec[i];
			for(int j = 0; j < Vec[i]; ++j)
			{
				string s;
				cin >> s;
				str[i].push_back(s);
			}
		}
		while(true)
		{
			bool update = false;
			for(int i = 0; i < m; ++i)
			{
				int sum = 0;
				for(int j = 0; j < Vec[i]; ++j)
				{
					sum += Map[str[i][j]];
				}
				if(Map[item[i]] > sum)
				{
					Map[item[i]] = sum;
					update = true;
				}
			}
			if(update == false)
			{
				break;
			}
		}
		string Target;
		cin >> Target;
		cout << Map[Target] << endl;
	}
}

int main()
{
	solve();
	return(0);
}

C++: // 2011/08/02 Tazoe

#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;

int min_cost(string str_itm, map<string, int>& itm, map<string, vector<string> >& rcp)
{
	// VsªÈ¢ê
	if(rcp.find(str_itm)==rcp.end())
		return itm[str_itm];

	int cost_rcp = 0;
	for(vector<string>::iterator p=rcp[str_itm].begin(); p<rcp[str_itm].end(); p++)
		cost_rcp += min_cost(*p, itm, rcp);

	if(cost_rcp<itm[str_itm])
		return cost_rcp;
	else
		return itm[str_itm];
}

int main()
{
	while(true){
		int n;
		cin >> n;
		if(n==0)
			break;

		map<string, int> itm;
		for(int i=0; i<n; i++){
			string str_i;
			int p;
			cin >> str_i >> p;
			itm[str_i] = p;
		}

		int m;
		cin >> m;

		map<string, vector<string> > rcp;
		for(int i=0; i<m; i++){
			string str_o;
			int k;
			cin >> str_o >> k;
			for(int j=0; j<k; j++){
				string str_q;
				cin >> str_q;
				rcp[str_o].push_back(str_q);
			}
		}

		string str_itm;
		cin >> str_itm;

		cout << min_cost(str_itm, itm, rcp) << endl;
	}

	return 0;
}

C++: #include<iostream>
#include<map>
#include<string>
using namespace std;
int main() {
	int n;
	while (cin >> n&&n != 0) {
		map<string, int>a;
		for (int i = 0; i < n; i++) {
			string b;
			int c;
			cin >> b >> c;
			a.insert(map<string, int>::value_type(b, c));
		}
		cin >> n;
		for (int i = 0; i < n; i++) {
			string b, c[100], d,h="";
			int e,f=0;
			getline(cin, d);
			d += " ";
			for (int i = 0; i < d.length(); i++) {
				if (d[i] == ' ') {
					if (f == 0) b = h;
					else if (f == 1) e = atoi(h.c_str());
					else c[f - 2] = h;
					h = "";
					f++;
				}
			}
			int g = 0;
			for (int j = 0; j < e; j++) {
				g += a[c[j]];
			}
			if (g < a[b]) {
				a[b] = g;
			}
		}
		string k;
		cin >> k;
		cout << a[k] << endl;
	}
}

C++: // 2010/12/22 Tazoe

#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;

int min_cost(string item, map<string, int>& items, map<string, vector<string> >& recipes)
{
	if(recipes.find(item)==recipes.end())
		return items[item];

	int cost_recipes = 0;
	for(vector<string>::iterator p=recipes[item].begin(); p<recipes[item].end(); p++)
		cost_recipes += min_cost(*p, items, recipes);

	if(cost_recipes<items[item])
		return cost_recipes;
	else
		return items[item];
}

int main()
{
	while(true){
		int n;
		cin >> n;
		if(n==0)
			break;

		map<string, int> items;
		for(int i=0; i<n; i++){
			string i_str;
			int p;
			cin >> i_str >> p;
			items[i_str] = p;
		}

		int m;
		cin >> m;

		map<string, vector<string> > recipes;
		for(int i=0; i<m; i++){
			string o_str;
			int k;
			cin >> o_str >> k;
			for(int j=0; j<k; j++){
				string q_str;
				cin >> q_str;
				recipes[o_str].push_back(q_str);
			}
		}

		string item;
		cin >> item;

		cout << min_cost(item, items, recipes) << endl;
	}

	return 0;
}