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 <string>
#include <utility>
#include <map>
#include <vector>
using namespace std;

int n, m, k;
string o;
vector<pair<string, vector<string> > > mix;
map<string, int> item;

int sum(vector<string> s) {
	int p = 0;
	for (int i = 0; i < s.size(); i++) {
		p += item[s[i]];
	}
	return p;
}

void update() {
	int p;
	for (int i = 0; i < m; i++) {
		p = sum(mix[i].second);
		if (p < item[mix[i].first]) {
			item[mix[i].first] = p;
		}
	}
}

int main(){
	while (cin >> n && n != 0) {
		item = map<string, int>();
		for (int i = 0; i < n; i++) {
			cin >> o >> k;
			item[o] = k;
		}
		cin >> m;
		mix = vector<pair<string, vector<string> > >(m);
		for (int i = 0; i < m; i++) {
			cin >> mix[i].first >> k;
			for (int j = 0; j < k; j++) {
				cin >> o;
				mix[i].second.push_back(o);
			}
		}
		for (int i = 0; i < 10000; i++) {
			update();
		}
		cin >> o;
		cout << item[o] << endl;
	}

	return 0;
}

C++: #include <iostream>
#include <map>
#include <vector>
using namespace std;
int main()
{
  for(;;){
    int n;
    cin >> n;
    if(n == 0) break;
    map<string,int> price;
    for(int i=0; i<n; i++){
      string s;
      int p;
      cin >> s >> p;
      price.insert(make_pair(s,p));
    }
    int m;
    cin >> m;
    map<string,vector<string> > recipe;
    for(int i=0; i<m; i++){
      string goal;
      cin >> goal;
      int j;
      cin >> j;
      int sum = 0;
      for(int k=0; k<j; k++){
        string src;
        cin >> src;
        sum += price[src];
        recipe[src].push_back(goal);
      }
      if(sum < price[goal]){
        int diff = price[goal] - sum;
        price[goal] = sum;
        vector<string>::iterator it;
        for(it = recipe[goal].begin(); it != recipe[goal].end(); it++){
          price[*it] -= diff;
        }
      }
    }
    string target;
    cin >> target;
    cout << price[target] << endl;    
  }
  return 0;
}

C++: #include <iostream>
#include <string>
using namespace std;

struct ITEM {
	string name;
	int cost;
	int recipeNum;
	int recipe[100];
};

int itemNum;
ITEM item[100];

int usedNum;
int used[100];

int renkin(int itemId);
int searchId(string name);

int main(){
	int i,j,n;
	string name;

	while(cin>>itemNum,itemNum){
		//item
		for(i=0;i<itemNum;i++) cin>>item[i].name>>item[i].cost;

		//recipe
		cin>>n;
		while(n--){
			cin>>name;i=searchId(name);
			cin>>item[i].recipeNum;
			for(j=0;j<item[i].recipeNum;j++){
				cin>>name;
				item[i].recipe[j]=searchId(name);
			}
		}

		cin>>name;usedNum=0;
		cout<<renkin(searchId(name))<<endl;
	}

	return 0;
}

int renkin(int itemId){
	long int work,result=0;
	int i,j;
	
	used[usedNum++]=itemId;
	for(i=0;i<item[itemId].recipeNum;i++){
		j=0;while(j<usedNum && used[j]!=item[itemId].recipe[i]) j++;
		if(j==usedNum){
			work=renkin(item[itemId].recipe[i]);
			usedNum--;
		}else{
			work=-1;
		}
		
		result+=(work!=-1)?work:item[item[itemId].recipe[i]].cost;
	}
	if(i==0 || item[itemId].cost<result) result=item[itemId].cost;

	return result;
}

int searchId(string name){
	int i=0;while(name!=item[i].name) i++;
	return i;
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define FFOR(i,a,b) for(int i=(a);i<=(b);i++)
#define REP(i,b) FOR(i,0,b)
#define RREP(i,b) FFOR(i,1,b)
#define PB push_back
#define F first
#define S second
#define BE(c) c.begin(),c.end()
using namespace std;
typedef long long LL;
typedef LL ut;
typedef long double ld;
typedef pair<ut,ut> pr;
typedef vector<pr> Vpr;
typedef vector<ut> VI;
typedef pair<ut,pr> ppr;
typedef priority_queue<pr,Vpr, greater<pr> > PQ;
const int SIZE=5+3*1e+4;
const ut INF=1<<30;
const ld eps=1e-6;
const LL p=7+1e+9;

int N, M;
map<string, int> items;
map<string, vector<string>> recipe;

int dfs(string s){
	int res = 0;
	if(recipe[s].empty()){
		return items[s];
	}
	else{
		REP(i,recipe[s].size()){
			res += min(items[recipe[s][i]], dfs(recipe[s][i]));
		}
		res = min(res, items[s]);
	}
	return res;
}

int main(){
	while(cin >> N && N){
		string s;
		int n;
		REP(i,N){
			cin >> s >> n;
			items[s] = n;
		}
		cin >> M;
		string c, q;
		int k;
		REP(i,M){
			cin >> c >> k;
			vector<string> tmp;
			REP(j,k){
				cin >> q;
				tmp.push_back(q);
			}
			recipe[c] = tmp;
		}
		string goal;
		cin >> goal;
		cout << dfs(goal) << endl;
	}
}

C++: #include <cstdio>
#include <iostream>
#include <map>
#include <string>
using namespace std;

typedef struct{
	string product;
	int num;
	string stuff[100];
}recipe;

int n, m;
map<string, long> mp; //普通に買うときの値段
recipe r[100];

long rec(string a){
	long ret=0;	
	int p=-1;
	
	//合成可能か
	bool find=false;
	for(int i=0; i<m; ++i){
		if(r[i].product==a){
			find=true;
			p=i;
			break;
		}
	}
	
	if( !find ) ret=mp[a]; //無理だった		
	else{
		for(int i=0; i<r[p].num; ++i){
			ret+=rec(r[p].stuff[i]);
		}
		
		ret=min(ret, mp[a]);
	}
	
	return ret;
}

int main(){
	while(1){		
		//入力
		scanf(" %d", &n);
		if(n==0) break;
		for(int i=0; i<n; ++i){
			string s;
			long p;
			cin >> s >> p;
			mp[s]=p;
		}
		
		scanf(" %d", &m);
		for(int i=0; i<m; ++i){
			cin >> r[i].product;
			cin >> r[i].num;
			for(int j=0; j<r[i].num; ++j) cin >> r[i].stuff[j];
		}
		
		string want;
		cin >> want;
		
		//処理
		printf("%ld\n", rec(want));
	}	
}