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<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<pair<string,pair<int,int> > > resipi;
vector<pair<string,int> >psi;

int main(){
  int n;
  while(cin>>n,n!=0){
    resipi.clear();
    psi.clear();
    ll cost=0;
    for(int i=0;i<n;i++){
      string str;int ne;cin>>str>>ne;
      psi.push_back(make_pair(str,ne));
    }
    int m;
    cin>>m;
    int ban=0,k=0;
    vector<string> sozai;
    for(int i=0;i<m;i++){
      string renkin;cin>>renkin;
      int snum;cin>>snum;
      for(int j=0;j<snum;j++){
	string s;
	cin>>s;
	sozai.push_back(s);
      }
      resipi.push_back(make_pair(renkin,make_pair(ban,ban+snum)));
      ban+=snum;
    }
    string product;
    cin>>product;
    int flag=0;
    int kane=0;
    for(int i=0;i<resipi.size();i++){
      kane=0;
      for(int j=resipi[i].second.first;j<resipi[i].second.second;j++){
	for(int l=0;l<psi.size();l++){
	  if(sozai[j]==psi[l].first)
	    kane+=psi[l].second;
	}
      }
      for(int j=0;j<psi.size();j++){
	if(resipi[i].first==psi[j].first && kane<psi[j].second){
	  psi[j].second=kane;
	  break;
	}
      }
    }
    for(int i=0;i<psi.size();i++)
      if(psi[i].first==product)
	cout<<psi[i].second<<endl;
  }
return 0;
}

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;
}