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<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<string>

using namespace std;

#define rep(i,n) for(int i=0;i<int(n);i++)
#define reps(i,n) for(int i=1;i<=int(n);i++)
#define sint(i) scanf("%d",&i);
#define sintt(i,j) scanf("%d%d",&i,&j);
#define sinttt(i,j,k) scanf("%d%d%d",&i,&j,&k);
#define sintttt(i,j,k,m) scanf("%d%d%d%d",&i,&j,&k,&m);

#define INF 1010000000
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};


int cost[101];
vector<int> haigo[101];

int saiki(int n){
	if(haigo[n].size()==0){
		return cost[n];
	}
	
	int sum=0;
	rep(i,haigo[n].size()){
		sum+=saiki(haigo[n][i]);
	}
	return min(cost[n],sum);
}

int main(){
	while(1){
		int n;
		sint(n);
		if(n==0)break;
		
		rep(i,101){
			haigo[i].clear();
		}
		
		map<string,int> sina;
		rep(i,n){
			string str;
			int a;
			cin>>str>>a;
			sina[str]=i;
			cost[i]=a;
		}
		
		int m;
		sint(m);
		
		
		rep(i,m){
			string a;
			int b;
			cin>>a>>b;
			rep(j,b){
				string c;
				cin>>c;
				haigo[sina[a]].push_back(sina[c]);
			}
		}
		
		string toi;
		cin>>toi;
		
		printf("%d\n",saiki(sina[toi]));
	}
}

C++: /*
 1 sÚ XgÉÜÜêéACeÌ n (®)
 2 sÚ æ 1 ÌACeÌîñ i p (¼p¶ñ ®;¼póæØè)
 3 sÚ æ 2 ÌACeÌîñ
 :
 n+1 sÚ æ n ÌACeÌîñ
 n+2 sÚ BàVsÌ m (®)
 n+3 sÚ æ 1 ÌBàVsÌîñ o k q1 q2 EEE qk
 (¼p¶ñ ® ¼p¶ñ EEE ¼p¶ñ;¼póæØè)
 n+4 sÚ æ 2 ÌBàVsÌîñ
 :
 n+m+2 sÚ æ m ÌBàVsÌîñ
 n+m+3 sÚ wè³ê½ACe¼ (¼p¶ñ)
 
 ACeXgÉÜÜêéACeÌíÞ n Í 1 Èã 100 ÈºÌ®
 eACeðwü·éêÌli p Í 0 Èã 1000000 Èº
 ACeÌ¼O i Í 1 ¶Èã 100 ¶Èº ÌAt@xbg©çÈé¼p¶ñ
 BàVsÌíÞ m Í 0 Èã 100 ÈºÌ®
 1 ÂÌBàVsÍACeÌ¼O o A»êðìé½ßÉKvÈACeÌÂ k A k ÂÌACe ¼ q ÌXgÉæÁÄ^¦çêÜ·Bk Í 100 ÈºÆµÜ·B
*/

#include <cstdio>
#include <string>
#include <map>
#include <vector>
using namespace std;

map <string, int> item;
map <string, vector<string> > recipe;
int n, m, k, money;
char name[101], o[101], material[101];

int dp(string str);

int main(void)
{
    
    while (1){
        scanf("%d", &n);
        if (n == 0) break;
        for (int i = 0; i < n; i++){
            scanf("%s %d", name, &money);
            item.insert( map<string, int>::value_type( name, money ) );
        }
        
        scanf("%d", &m);
        for (int i = 0; i < m; i++){
            scanf("%s %d", o, &k);
            for (int j = 0; j < k; j++){
                scanf("%s", material);
                recipe[o].push_back(material);
            }
        }
        
        scanf("%s", name);
        printf("%d\n", dp(name));
        
        item.clear();
    }
    
    return (0);
}

int dp(string str)
{
    int ans = 0;
    
    if (recipe[str].size() != 0){
        for (int i = 0; i < recipe[str].size(); i++){
            ans += dp(recipe[str][i]);
        }
    }
    else {
        ans = item[str];
    }
    
    if (item[str] < ans) ans = item[str];
    
    return ans;
}

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

using namespace std;
int n,m;
map<string,int > buy;
map<string,pair<int,vector<string> > > make;

int cal(string s){
  int ret1,ret2;
  //cout<<"name:"<<s<<endl;
  ret1 = buy[s];
  if( make.find(s) != make.end() ){
    pair<int,vector<string> > p = make[s];
    int k = p.first;
    ret2 = 0;
    for(int i = 0;i<k;i++){
      ret2 += cal((p.second)[i]);
    }    
  }else{
    ret2 = 1111111111;
  }
  return min(ret1,ret2);
  

}

int main(){
  while(cin>>n){
    if(n==0)
      return 0;
    buy.clear();
    make.clear();
    for(int i = 0;i<n;i++){
      string s;
      int p;
      cin>>s>>p;
      buy[s] = p;
    }
    cin>>m;
    for(int i = 0;i<m;i++){
      string s,tmp;
      int k;
      vector<string> tmp_v;
      cin>>s;
      cin>>k;
      for(int j = 0;j<k;j++){
	cin>>tmp;
	tmp_v.push_back(tmp);
      }
      make[s] = make_pair(k,tmp_v);
    }
    string t;
    cin>>t;
    cout<<cal(t)<<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);
        return 0;
        cout << dfs(dict.get(target), memo, visiting, materials) << endl;
    }
    return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<map>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
map<string,vector<string> > mp;
map<string,int> vec;
int func(string s){
	int sum=0;
	if(mp[s].size()==0)
	sum=100000000;
	else
	rep(i,(int)mp[s].size()){
		sum+=func(mp[s][i]);
	}
	return min(vec[s],sum);
}
int main(){
	int n,x;
	string s,a;
	while(cin>>n,n){
		rep(i,n){
			cin>>s>>x;
			vec[s]=x;
		}
		cin>>n;
		while(n--){
			cin>>s;
			cin>>x;
			rep(i,x){
				cin>>a;
				mp[s].push_back(a);
			}
		}
		cin>>s;
		cout<<func(s)<<endl;
		mp.clear();
		vec.clear();
	}
	return 0;
}