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 <stdio.h>
#include <math.h>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <iomanip>
#include <iostream>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) cerr << #x << "=" << static_cast<bitset<16> >(x) << endl;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,m,n) for (int i=m;i<(int)(n);i++)
#define if_range(x, y, w, h) if (0<=(int)(x) && (int)(x)<(int)(w) && 0<=(int)(y) && (int)(y)<(int)(h))

const int INF = 100000000;
typedef double D;
const double EPS = 1e-8;
const double PI = 3.14159;
int dx[4]={-1, 0, 1, 0}, dy[4]={0, -1, 0, 1};
using namespace std;
typedef pair<int, int> PII;

/** Problem0201 : Wrought Gold Master **/
map<string, int> item;
map<string, vector<string> > recipe;

int min_price(string t)
{
	int res = item[t];
	if (recipe[t].size()) {
		int tmp=0;
		rep(i, recipe[t].size()) {
			tmp += min_price(recipe[t][i]);
		}
		res = min(res, tmp);
	}
	return res;
}

int main()
{
	int N, M;
	while (cin>>N, N) {
		item.clear(); recipe.clear();
		
		rep(i, N) {
			string s; int a;
			cin>>s>>a;
			item[s]=a;
		}
		cin>>M;
		rep(i, M) {
			string s; int k;
			cin>>s>>k;
			rep(j, k) {
				string ss; cin>>ss;
				recipe[s].push_back(ss);
			}
		}
		
		string target;
		cin >> target;
		cout << min_price(target) << endl;
	}
}

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

using namespace std;

map<string,int> dp;
map<string,int> buy;
map<string, vector<string> > reci;

const int INF = 1000000;

#define rep(i,a) for(int i=0; i<(a); i++)

int solve(string to){
  int ari = 0;
  rep(i,reci[to].size()){
    ari += solve(reci[to][i]);
  }
  if(ari == 0){
    ari = buy[to];
  }
  
  int rtn = min(ari, dp[to]);
  dp[to] = rtn;
  return rtn;
}


int main(){
  int n;
  while(cin >> n, n){
    dp.clear();
    buy.clear();
    reci.clear();
    rep(i,n){
      string str; int p;
      cin >> str >> p;
      buy[str] = p;
      dp[str] = INF;
    }
    int r; cin >> r;
    rep(i,r){
      string str; int m;
      cin >> str >> m;
      rep(j,m){
	string ing;
	cin >> ing;
	reci[str].push_back(ing);
      }
    }

    // solve

    string to; cin >> to;
    cout << solve(to) << endl;
  }
  return 0;
}

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

using namespace std;
typedef unsigned long long ULL;

struct Dict {
    map<string,int> dict;
    int id;
    Dict() : id(0) {}

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

ULL dfs(int pos, vector<ULL> &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;
    ULL acc = 0;
    for(vector<int>::const_iterator it = list.begin(); it != list.end(); ++it) {
        acc += dfs(*it, memo, visiting, materials);
    }
    visiting[pos] = 0;
    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<ULL> 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<ULL> memo(price);
        vector<int> visiting(N, 0);
        cout << dfs(dict.get(target), memo, visiting, materials) << endl;
        return 0;
    }
    return 0;
}

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

const int INF = (1 << 30) - 1;
int main()
{
    int N, M;

    while ( cin >> N, N ) {

        bool path[105][105] = {};
        int value[105];
        int memo[105];

        string purpose;
        unordered_map < string , int > hash;

        for ( int i = 0; i < N; i++ ) {
            string name;
            cin >> name >> value[i];
            hash[name] = i;
        }

        cin >> M;
        for ( int p = 0; p < M; p++ ) {
            string node;
            int k;
            cin >> node >> k;
            for ( int i = 0; i < k; i++ ) {
                string to;
                cin >> to;
                path[ hash[node] ][ hash[to] ] = true;
            }
        }

        cin >> purpose;
        memset(memo, -1, sizeof(memo));
        function < int(int) > calc = [&]( int v )
        {
            if ( memo[v] == -1 ) {
                memo[v] = INF;
                for ( int i = 0; i < N; i++ ) {
                    if ( path[v][i] ) {
                        if ( memo[v] == INF ) {
                            memo[v] = 0;
                        }
                        memo[v] += calc(i);
                    }
                }
                memo[v] = min(memo[v], value[v]);
            }
            return ( memo[v] );
        };

        cout << calc(hash[purpose]) << endl;
    }

    return (0);
}

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

using namespace std;

map<string,int> pm;
map<string,vector<string> >rm;

int cost(string s){
  if(rm.find(s)!=rm.end()){
    int c=0;
    for(int i=0;i<rm[s].size();i++){
      c+=cost(rm[s][i]);
    }
    return min(c,pm[s]);
  }else{
    return pm[s];
  }
}

int main(){
  for(int n;cin>>n,n;){
    pm.clear();
    rm.clear();
    for(int i=0;i<n;i++){
      string i;
      int p;
      cin>>i>>p;
      pm[i]=p;
    }
    int m;
    cin>>m;
    for(int i=0;i<m;i++){
      string p;
      int k;
      cin>>p>>k;
      while(k--){
	string q;
	cin>>q;
	rm[p].push_back(q);
      }
    }
    string a;
    cin>>a;
    cout<<cost(a)<<endl;
  }
  return 0;
}