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

	cout<<"test\n";

	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){
	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[itemId].cost)?work:item[itemId].cost;
	}
	if(i==0) 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<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);
			}
		}
	}
	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;
			}
		}
	}
	return num;
}

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

using namespace std;

map<string,int> s1;
map<string,vector<string> > s2;
int INF=100000000;
int gold(string s){
	int res=0;
	int res2=INF;
	res=s1[s];
	if(s2[s].size()>0)res2=0;
	for(int i=0;i<s2[s].size();i++){
		res2+=gold(s2[s][i]);
	}
	res=min(res,res2);
	return res;
}

int main(void){
	int n,m;
	while(1){
		scanf("%d",&n);
		if(n==0)break;
		s1.clear();
		s2.clear();
		for(int i=0;i<n;i++){
			string str;
			int c;
			cin >> str >> c;
			s1[str]=c;
		}
		scanf("%d",&m);
		for(int i=0;i<m;i++){
			string str;
			int k;
			cin >> str >> k;
			for(int j=0;j<k;j++){
				string s;
				cin >> s;
				s2[str].push_back(s);
			}
		}
		string s3;
		cin >> s3;
		printf("%d\n",gold(s3));
	}
    return 0;
}

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

using namespace std;

typedef struct _item{
	int value;
	vector<string> resipi;
}item;

vector<string>::iterator vp;

map<string,item> minlist;
map<string,item>::iterator mp;

int n,m;

int main(){
	
	
	while(cin>>n,n){
		
		minlist.clear();
		
		for(int i=0;i<n;i++){
			string name;
			int v;
			cin>>name>>v;
			minlist[name].value=v;
		}
		
		cin>>m;
		
		for(int i=0;i<m;i++){
			string name;
			cin>>name;
			
			int o;
			cin>>o;
			for(int j=0;j<o;j++){
				string genryou;
				cin>>genryou;
				minlist[name].resipi.push_back(genryou);
			}
		}
		
		int flag=1;
		
		
		while(flag){
			flag=0;
			for(mp=minlist.begin();mp!=minlist.end();mp++){
				int tvalue=0;
				if(mp->second.resipi.size()==0)continue;
				for(vp=mp->second.resipi.begin();vp!=mp->second.resipi.end();vp++){
					tvalue+=minlist[*vp].value;
				}
				if(tvalue<(mp->second.value)){
					mp->second.value=tvalue;
					flag=1;
				}
			}
		}
		
		string target;
		cin>>target;
		cout<<minlist[target].value<<endl;
	}
	return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int,int> pii;
//template<typename T> using vec=std::vector<T>;

const int inf=1<<30;
const long long int infll=1LL<<58;
const double EPS=1e-9;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
	os << "[";
	for (const auto &v : vec) {
		os << v << ",";
	}
	os << "]";
	return os;
}

map<string,int> table;
map<string,vector<string>> recipe;

int dfs(string &name,map<string,bool>& used){
    used[name]=true;
    int res=table[name];
    if(recipe[name].empty()) return res;

    int tmp=0;
    for(auto &next:recipe[name]){
        if(used[next]) return res;
        tmp+=dfs(next,used);
    }
    res=min(res,tmp);

    return res;
}

void solve(){
    int n;
    while(true){
        cin >> n;
        if(!n) break;

        table.clear();
        rep(i,0,n){
            string name;
            int cost;
            cin >> name >> cost;
            table[name]=cost;
        }

        int m;
        cin >> m;
        recipe.clear();
        rep(i,0,m){
            string name1;
            int k;
            cin >> name1 >> k;
            rep(j,0,k){
                string name2;
                cin >> name2;
                recipe[name1].push_back(name2);
            }
        }

        string str;
        cin >> str;
        map<string,bool> used;
        cout << dfs(str,used) << endl;
    }
}

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	solve();
	return 0;
}