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

#define min(a,b) ((a)<(b)?(a):(b))

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

int get_lowest_price(string name) {
    if (recipe.find(name) == recipe.end()) {
        return item[name];
    }
    vector<string> m = recipe[name];
    int mat_price = 0;
    for (vector<string>::iterator e = m.begin(); e != m.end(); e++) {
        mat_price += get_lowest_price(*e);
    }
    return min(item[name], mat_price);
}

int main() {
    string name;
    int price, i, n, m;

    while ((cin >> n) && n) {
        item.clear();
        for (i = 0; i < n; i++) {
            cin >> name >> price;
            item[name] = price;
        }

        cin >> m;
        recipe.clear();
        for (i = 0; i < m; i++) {
            vector<string> material;
            int k;
            cin >> name >> k;
            while (k--) {
                string itm;
                cin >> itm;
                material.push_back(itm);
            }
            recipe[name] = material;
        }
        cin >> name;
        cout << get_lowest_price(name) << endl;

    }
    return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<cassert>
#include<map>
#include<vector>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define N 100

const int INF = 1000100; 
int table[N];
int buycost[N];

int solve(int now,vector<int> *make){
  if ( table[now] != -1)return table[now];
  if(  make[now].size()==0)return table[now]=buycost[now];
  

  int ret = buycost[now],tmp=0;  
  rep(i,make[now].size()){
    tmp+=solve(make[now][i],make);
  }
  
  ret= min(ret,tmp);
  return table[now]=ret; 
}

main(){
  int n;
  while(cin>>n && n){
    map<string,int> M;
    rep(i,n){
      string t;int a;
      cin>>t>>a;
      M[t]=i;
      buycost[i]=a;
      table[i]=-1;
    }
    
    vector<int> make[n];
    cin>>n;
    rep(i,n){
      string a;
      cin>>a;
      int now =M[a],m;
      cin>>m;
      rep(j,m){
	cin>>a;
	make[now].push_back(M[a]);
      }     
    }
    string tmp;
    cin>>tmp;
    int tar=M[tmp];
    cout << solve(tar,make) << endl;
    
  }
  return false;
}

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

using namespace std;

struct Dict {
    map<string,int> dict;

    int get(const string &name) {
        if(dict.count(name)) return dict[name];
        const int id = dict.size();
        return dict[name] = id;
    }
};

int dfs(int pos, vector<int> &memo, vector<int> &visiting, const vector<vector<int> > &materials) {
    const vector<int> &list = materials[pos];
    if(visiting[pos]) return memo[pos];
    if(list.size() == 0) return memo[pos];

    visiting[pos] = 1;
    int acc = 0;
    for(vector<int>::const_iterator it = list.begin(); it != list.end(); ++it) {
        acc += dfs(*it, memo, visiting, materials);
    }
    return memo[pos] = min(acc, memo[pos]);
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while(true) {
        int N;
        cin >> N;
        if(!N) break;

        Dict dict;
        vector<int> price(N);
        vector<vector<int> > materials(N);
        for(int i = 0; i < N; ++i) {
            string name;
            int p;
            cin >> name >> p;
            price[dict.get(name)] = p;
        }
        int M;
        cin >> M;
        for(int i = 0; i < M; ++i) {
            string to;
            cin >> to;
            const int to_id = dict.get(to);
            int cnt;
            cin >> cnt;
            while(cnt--) {
                string material;
                cin >> material;
                materials[to_id].push_back(dict.get(material));
            }
        }
        string target;
        cin >> target;
        vector<int> memo(price);
        vector<int> visiting(N, 0);
        cout << dfs(dict.get(target), memo, visiting, materials) << endl;
    }
    return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count etc.
#include <cstdlib>	// require abs
#include <cstdio>	// require printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen

using namespace std;

map <string, int> minC;

void dfs (string qns, map <string, vector <string> > rela )
{

	int prev = minC[qns];

	int sum = 0;
	map <string, vector <string> >::iterator it = rela.begin();
	for (; it != rela.end(); ++it ){
		if ((*it).first == qns ){
			vector <string> r = (*it).second;
			vector <string>::iterator jt = r.begin();
			for (; jt != r.end(); ++jt ){
				sum += minC[(*jt)];
			} // end for
			if (sum < minC[qns] ){
				minC[qns] = sum;
			} // end if
			break;
		} // end if
	} // end for

	if (prev != minC[qns] ){
		vector <string>::iterator it = rela[qns].begin();
		for (; it != rela[qns].end(); ++it ){
			dfs (*it, rela );
		} // end for
		dfs (qns, rela );
	}else{
		return;
	}
}

int main()
{
//	cut here before submit 
//	freopen ("testcase.wgm", "r", stdin );
	int n, m;

	while (cin >> n && n ){
		minC.clear();
		for (int i = 0; i < n; ++i ){
			string ite = "";
			int cost;
			cin >> ite >> cost;
			minC[ite] = cost;
		} // end for
		cin >> m;
		map <string, vector <string> >	rela;
		for (int i = 0; i < m; ++i ){
			string s = "";
			cin >> s;
			int num;
			cin >> num;
			vector <string> t (num );
			for (int j = 0; j < num; ++j ){
				cin >> t[j];
			} // end for
			rela[s] = t;
		} // end for
		string qns;
		cin >> qns;
		
		dfs (qns, rela );

		cout << minC[qns] << endl;
	} // end loop
		
	return 0;
}