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 <fstream>
#include <sstream>
#include <iomanip>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <functional>
#include <utility>
#include <algorithm>
#include <numeric>
#include <typeinfo>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <ctime>

using namespace std;

#define dump(n) cout<<"# "<<#n<<"="<<(n)<<endl
#define debug(n) cout<<__FILE__<<","<<__LINE__<<": #"<<#n<<"="<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define iter(c) __typeof((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();i++)
#define allof(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int,int> pii;

int solve(string& name,map<string,int>& prices,map<string,vs>& needs)
{
	if(needs.count(name)==0)
		return prices[name];
	int res=0;
	foreach(i,needs[name])
		res+=solve(*i,prices,needs);
	return min(prices[name],res);
}

int main()
{
	for(int n;cin>>n,n;){
		map<string,int> prices;
		rep(i,n){
			string name;
			int price;
			cin>>name>>price;
			prices[name]=price;
		}
		map<string,vs> needs;
		int m;
		cin>>m;
		rep(i,m){
			string name;
			int k;
			cin>>name>>k;
			rep(j,k){
				string elem;
				cin>>elem;
				needs[name].push_back(elem);
			}
		}
		
		string name;
		cin>>name;
		cout<<solve(name,prices,needs)<<endl;
	}
	
	return 0;
}

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

typedef long long ll;
typedef pair<int, int> P;

#define pb push_back
#define rep(i, a, n) for(int i = (a); i < (n); i++)
#define dep(i, a, n) for(int i = (a); i >= (n); i--)
#define mod 1e9+7

__attribute__((constructor))
void initial() {
  cin.tie(0);
  ios::sync_with_stdio(false);
}

int main() {
  int n;
  while(cin >> n) {
    if(!n) return 0;
    map<string, int> m;
    rep(i, 0, n) {
      string s;
      int p;
      cin >> s >> p;
      m[s] = p;
    }

    cin >> n;
    string o[100];
    vector<string> q[100];
    rep(i, 0, n) {
      cin >> o[i];
      int k;
      cin >> k;
      rep(j, 0, k) {
        string sum;
        cin >> sum;
        q[i].pb(sum);
      }
    }

    rep(i, 0, 100) {
      rep(j, 0, n) {
        int f = 0;
        int gou = 0;
        rep(k, 0, q[i].size()) {
          if(m.count(q[i][k])) {
            gou += m[q[i][k]];
          }else f = 1;
        }
        if(!f) {
          if(m.count(o[i])) {
            m[o[i]] = min(m[o[i]], gou);
          }else m[o[i]] = gou;
        }
      }
    }

    string s;
    cin >> s;
    cout << m[s] << endl;
  }
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#define mp make_pair
using namespace std;
map<string,vector<string> > recipe;
map<string,int>items;

int price(string item){
  if(recipe.find(item) != recipe.end()){
    int p=0;
    for(int i=0;i<recipe[item].size();i++)
      p+= price(recipe[item][i]);
    return min(p,items[item]);
  }
  else return items[item];
}

int main(){
  int n,m,k;
  while(true){
    cin>>n;
    if(!n)break;
    string name;
    int pr;
    items.clear();
    recipe.clear();
    for(int i=0;i<n;i++){
      cin>>name>>pr;
      items.insert(mp(name,pr));
    }
    cin>>m;
    for(int j=0;j<m;j++){
      cin>>name>>k;
      vector<string> material;
      string mat_name;
      for(int i=0;i<k;i++){
	cin>>mat_name;
	material.push_back(mat_name);
      }
      recipe.insert(mp(name,material));
    }
    cin>>name;
    cout<<price(name)<<endl;
  }
  return 0;
}

C++: #include <iostream>
#include <vector>
#include <map>
//#include <fstream>	// require freopen

using namespace std;

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

	while (cin >> n && n ){
		map <string, int > item;
		for (int i = 0; i < n; ++i ){
			string name; int money;
			cin >> name >> money;
			if (item.find (name) == item.end() || item[name] > money){
				item[name] = money;
			} // end if
		} // end for
		cin >> m;
		map <string, vector <string> > recipe;
		for (int i = 0; i < m; ++i ){
			string p; int k; vector <string> t;
			cin >> p >> k;
			for (int j = 0; j < k; ++j){
				string q;
				cin >> q; t.push_back(q);
			} /// end for
			recipe[p] = t;
		} // end for
		map <string, int > pre_item;

		do{
			pre_item = item;

			map<string, int>::iterator it = item.begin();
			for (; it != item.end(); ++it ){
				string r = (*it).first;
				if (!recipe[r].empty() ){
					vector <string>::iterator jt = recipe[r].begin();
					int res = 0;
					for (; jt != recipe[r].end(); ++jt ){
						map <string, int >::iterator kt = item.begin();
						bool found = false;
						for (; kt != item.end(); ++kt ){
							if ((*jt) == (*kt).first ){
								res += (*kt).second;
								found = true;
							} // end if
						} // end for
						if (!found ){
							break;
						} // end if
					} // end for
					if (jt == recipe[r].end() ){
						item[r] = res;
					} // end if
				} // end if
			} // end for
		}while (pre_item != item );

		string search;
		cin >> search;
		cout << item[search] << endl;

	} // end loop
		
	return 0;
}

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

using namespace std;

typedef map<string, int> item_price_map;
//typedef map<string, vector<string>> renkin_map;

item_price_map price_table;

bool get_input() {
    int n, m;

    string name;
    int price;
    cin >> n;
    if (n == 0) return false;
    for (int i = 0; i < n; i++) {
        cin >> name >> price;
        price_table[name] = price;
    }

    vector<string> items;
    int count;
    cin >> m;
    for (int i = 0; i < m; i++) {
        cin >> name >> count;
        items.resize(count);
        for (int j = 0; j < count; j++) {
            cin >> items[j];
        }
        int min_price = 0;
        for (int j = 0; j < count; j++) {
            min_price += price_table[items[j]];
        }
        price_table[name] = min_price < price_table[name] ? min_price : price_table[name];
    }

    return true;
}

void solve() {
    string name;
    cin >> name;
    cout << price_table[name] << endl;
}

int main() {
    while (get_input()) {
        solve();
    }
    return 0;
}