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 <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
int main(){
  int n;
  map<string, int> items;
  string name;
  int value;
  
  while(cin >> n, n){
    for(int i = 0 ; i < n ; i++){
      cin >> name >> value;
      items.insert(make_pair(name, value));
    }
    int m;
    int total;
    string names[101];
    cin >> n;
    for(int i = 0 ; i < n ; i++){
      total = 0;
      cin >> name;
      cin >> m;
      for(int j = 0 ; j < m ; j++){
	cin >> names[i];
	total += items[names[i]];
      }
      items[name] = min(items[name], total);
    }
    cin >> name;
    cout << items[name] << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <set>
#include <map>
#include <queue>
#include <string>

using namespace std;

typedef pair<string, int> psi;

int main(){
	while(true){
		int n, m;
		scanf("%d", &n);
		if(n == 0){ break; }
		map<string, int> items;
		for(int i = 0; i < n; i++){
			string name;
			int cost;
			cin >> name >> cost;
			items.insert(psi(name, cost));
		}
		map< string, set<string> > materials;
		queue<string> q;
		scanf("%d", &m);
		for(int i = 0; i < m; i++){
			string item;
			int k, cost = 0;
			set<string> material;
			cin >> item >> k;
			for(int j = 0; j < k; j++){
				string name;
				cin >> name;
				material.insert(name);
				cost += items[name];
			}
			materials.insert(pair< string, set<string> >(item, material));
			if(cost < items[item]){
				items[item] = cost;
				q.push(item);
			}
		}
		while(!q.empty()){
			string item = q.front();
			q.pop();
			map< string, set<string> >::iterator it = materials.begin();
			while(it != materials.end()){
				if((*it).second.find(item) != (*it).second.end()){
					int cost = 0;
					set<string>::iterator jt = (*it).second.begin();
					while(jt != (*it).second.end()){
						cost += items[*jt];
						jt++;
					}
					if(cost < items[(*it).first]){
						items[(*it).first] = cost;
						q.push((*it).first);
					}
				}
				it++;
			}
		}
		string query;
		cin >> query;
		printf("%d\n", items[query]);
	}
	return 0;
}

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

#define INF (1 << 8)

using namespace std;

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

int rec(string item)
{
    if(recipe[item].size() == 0) {
        return table[item];
    } else {
        int ret = 0;
        for(int i = 0; i < recipe[item].size(); i++) ret += rec(recipe[item][i]);
        return min(ret, table[item]);
    }
}

int main()
{
    int N, R; 
    while(cin >> N && N) {
        table.clear();
        for(int i = 0; i < N; i++) {
            int v; string name;
            cin >> name >> v;
            table.insert( map<string, int>::value_type(name, v));
        }
        
        cin >> R;
        recipe.clear();
        for(int i = 0; i < R; i++) {
            int n; string name, tmp; vector<string> child;
            cin >> name >> n;
            for(int j = 0; j < n; j++) {
                cin >> tmp;
                child.push_back(tmp);
            }
            recipe.insert( map<string, vector<string> >::value_type(name, child));
        }

        string query;
        cin >> query;
        cout << rec(query) << endl;
    }
}

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

map<string, int> mp;

int main() {
  int n, p, m, k;
  string s, t;
  
  while(cin >> n, n) {
    mp.clear();
    for(int i=0; i<n; i++) {
      cin >> s >> p;
      mp[s] = p;
    }
    
    cin >> m;
    for(int i=0; i<m; i++) {
      cin >> s >> k;
      int temp = 0;
      for(int j=0; j<k; j++) {
	cin >> t;
	temp += mp[t];
      }
      if(temp<mp[s]) mp[s] = temp;
    }
    
    cin >> s;
    cout << mp[s] << endl;
  }
  
  return 0;
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<utility>
#include<vector>
using namespace std;
typedef pair<string, int>P;

int main() {
	int n;
	while (cin >> n, n) {
		vector<P>v;
		for (int i = 0;i < n;i++) {
			string sa;
			int a;
			cin >> sa >> a;
			v.push_back(P(sa, a));
		}

		int m;
		cin >> m;
		for (int i = 0;i < m;i++) {
			string s;
			cin >> s;
			int a;
			cin >> a;

			int it=-1;
			int mny = 0;
			for (int j = 0;j < a;j++) {
				string sb;
				cin >> sb;
				for (int k = 0;k < n;k++) {
					if (sb == v[k].first) {
						mny += v[k].second;
					}
				}
			}
			for (int j = 0;j < v.size();j++) {
				if (s == v[j].first)it = j;
			}
			if (it == -1)v.push_back(P(s, mny));
			else v[it].second = min(v[it].second,mny);
		}

		string ans;
		cin >> ans;
		for (int i = 0;i < v.size();i++) {
			if (ans == v[i].first) {
				cout << v[i].second << endl;
				break;
			}
		}
	}
	return 0;
}

C++: #include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;
map<string, int> items;
map<string, vector<string> > combs;

int rec(string name){
  if (combs.count(name) == 0)
    return items[name];
  int sum = 0;
  for (int i=0;i<combs[name].size();i++){
    sum += rec(combs[name][i]);
  }
  return min(sum, items[name]);
}

int main(){
  int m, n, l, cost;
  string name, tmp;
  while (cin >> n && n){
    items.clear();
    combs.clear();
    for (int i=0;i<n;i++){
      cin >> name;
      cin >> cost;
      items[name] = cost;
    }
    cin >> m;
    for (int i=0;i<m;i++){
      cin >> name >> l;
      for (int j=0;j<l;j++){
        cin >> tmp;
        combs[name].push_back(tmp);
      }
    }
    cin >> name;
    cout << rec(name) << endl;
  }

  return 0;
}