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
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <string>
#include <bitset>
using namespace std;
#define rep(I,N) for(int I = 0; I < (int)(N); I++)
#define FIN(V) cout<<V<<endl
#define pb push_back
#define INF (1 << 30)
typedef pair<int, int> P;
typedef long long ll;
typedef priority_queue<int> pq;
int StrToInt(string);
string IntToStr(int);
int solve(map<string, int> list, map<string, vector<string> > lesp, string make){
	vector<string> item = lesp[make];
	int mini = INF;
	int cost = 0;
	rep(i, item.size()){
		if(!lesp[item[i]].empty()){
			cout << "item" << endl;
			cost += solve(list, lesp, item[i]);
		}else{
			cost += list[item[i]];
		}
	}
	mini = min(mini, cost);
	return mini;
}

int main(void){
	int n, m;
	while(cin >> n, n){
		map<string, int> LIST;
		string MAKE;
		rep(i, n){
			string s;
			int cost;
			cin >> s >> cost;
			LIST[s] = cost;
		}
		cin >> m;
		map<string, vector<string> > LESP;
		rep(i, m){
			string s;
			cin >> s;
			int num;
			cin >> num;
			vector<string> v;
			rep(j, num){
				string L;
				cin >> L;
				v.push_back(L);
			}
			LESP[s] = v;
		}
		cin >> MAKE;
		if(m == 0){
			cout << LIST[MAKE] << endl;
			continue;
		}
		int ans = solve(LIST, LESP, MAKE);
		FIN(ans);

	}


	return 0;
}



int StrToInt(string s){
	stringstream ss;
	ss << s;
	int val;
	ss >> val;
	return val;
}
string IntToStr(int i){
	stringstream ss;
	ss << i;
	return ss.str();
}

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

using namespace std;

map<string, int> InputMaterial(int n);
map< string, map<string, int> > InputWrought(int n);
int Calculate(const string, map<string, int>, map< string, map<string, int> >);

int main(){
  int n, m;
  string str;
  map<string, int> material;
  map< string, map<string, int> > wrought;

  while(1){
    cin >> n;
    if(n == 0) break;
    material = InputMaterial(n);

    cin >> n;
    wrought = InputWrought(n);

    cin >> str;
    cout << Calculate(str, material, wrought) << endl;
  }
  return 0;
}

map<string, int> InputMaterial(int n){
  int i, m;
  string str;
  map<string, int> data;

  for(i=0; i<n; ++i){
    cin >> str >> m;
    data.insert(make_pair(str, m));
  }
  return data;
}

map< string, map<string, int> > InputWrought(int n){
  int i, j, m;
  string str, _str;
  map<string, int> _data;
  map< string, map<string, int> > data;
  map<string, int>::iterator iter;

  for(i=0; i<n; ++i){
    cin >> str >> m;
    for(j=0; j<m; ++j){
      cin >> _str;
      iter = _data.find(_str);
      if(iter == _data.end()) _data.insert(make_pair(_str, 1));
      else ++iter->second;
    }
    data.insert(make_pair(str, _data));
    _data.clear();
  }
  return data;
}

int Calculate(const string one_material, map<string, int> material,
	      map< string, map<string, int> > wrought){
  int n, sum;
  map<string, int>::iterator i, j;
  map< string, map<string, int> >::iterator k;

  i = material.find(one_material);
  if(i == material.end()) return -1;

  k = wrought.find(one_material);
  if(k == wrought.end()) return i->second;

  for(j=k->second.begin(), sum=0; j!=k->second.end(); ++j){
    n = Calculate(j->first, material, wrought);
    if(n == -1) return i->second;
    sum += (n * j->second);
  }
  if(sum > i->second) return i->second;
  else return sum;
}

C++: #include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <map>

using namespace std;

#define reep(i,f,n) for(int i=f; i<int(n); ++i)
#define rep(i,n) reep(i,0,n)

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

map<string, int> price;
map<string, vector<string> > resipi;

map<string, int> memo;

int solve(string str)
{
	if(memo.count(str))
		return memo[str];
	
	memo[str] = -1;
	
	if(!resipi.count(str))
		return memo[str] = price[str];
	
	int cost = 0;
	rep(i, resipi[str].size()){
		int a = solve(resipi[str][i]);
		if(a == -1)
			return memo[str] = price[str];
		
		cost += a;
	}
	
	printf("%s is %d\n", str.c_str(), min(price[str], cost));
	return memo[str] = min(price[str], cost);
}

int main()
{
	int n;
	while(scanf("%d", &n), n){
		price.clear();
		resipi.clear();
		memo.clear();
		
		rep(i, n){
			char name[128];
			int p;
			scanf("%s%d", name, &p);
			price[string(name)] = p;
		}
		
		int m;
		scanf("%d", &m);
		rep(i, m){
			char name[128];
			int k;
			scanf("%s%d", name, &k);
			rep(j, k){
				char factor[128];
				scanf("%s", factor);
				resipi[string(name)].push_back(string(factor));
			}
		}
		
		char name[128];
		scanf("%s", name);
		printf("%d\n", solve(string(name)));
	}
	
	return 0;
}

C++: #include<iostream>
#include <stdio.h>
#include <vector>
#include<string>
using namespace std;
int ha(string);
void saga(void);

struct L{
	string name;
	int cost;
};
struct  R{
	string name;
	string zairyo[101];
	int size;
};
int q,m,n;
L list[101];
R resipi[101];

int main()
{	
	int i,j,k,b=0,s,a;
	string S;
	while((cin>> n)!="EOF"){
	q=n;
	for(i=0;i<n;i++){
		cin  >> list[i].name>> list[i].cost;
	}


	cin>>m;
	for(i=0;i<m;i++){
		cin>>resipi[i].name>>b;
		resipi[i].size=b;
		for(j=0;j<b;j++){
		cin>>resipi[i].zairyo[j];
		}
		
	}
	cin>>S;

	
	/*for(i=0;i<n;i++){
		cout <<list[i].name<< list[i].cost<<endl;
	}
	for(i=0;i<m;i++){
		cout<<resipi[i].name;
		for(j=0;j<resipi[i].size;j++){
			cout<<resipi[i].zairyo[j];
		}
		cout<<endl;
	}
	*/
	cout<<ha(S)<<endl;
	}
	return 0;

}
int ha(string S)
{
	int  i,j,f=0,sum=0;
	for(i=0;i<m;i++){
		//cout<<S<<endl<<resipi[i].name;	
	if(S==resipi[i].name){
		f=1;
		break;
	}
	}
	if(f==1){
		for(j=0;j<resipi[i].size;j++){
			sum=sum+ha(resipi[i].zairyo[j]);
			}
		//printf("%d\n",sum);
		for(i=0;i<n;i++){
		if(S==list[i].name){
		if(sum<list[i].cost){
		return sum;
		}
		else return list[i].cost;
		}
	}
		
		}

	for(i=0;i<n;i++){
		if(S==list[i].name){
		return list[i].cost;
		}
	
	}

	
}