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

int main(){
    while(true){
        int n;
        cin >> n;
        if(n == 0)  break;

        map<string, int> table;

        string s;
        int p;

        for(int i = 0; i < n; i++){
            cin >> s >> p;
            table[s] = p;
        }

        int m;
        cin >> m;

        map<string, set<string>> recipe;
        for(int i = 0; i < m; i++){
            cin >> s >> p;
            string ingre;
            for(int i = 0; i < p; i++){
                cin >> ingre;
                recipe[s].insert(ingre);
            }
        }

        bool update = true;
        while(update){
            update = false;
            for(pair<string, set<string>> re : recipe){
                int cost = 0;
                //bool judge = true;

                for(string x : re.second){
                    // if(table.count(x) == 0){
                    //     judge = false;
                    //     break;
                    // }
                    cost += table[x];
                }

                if(/*judge && */
                    (table.count(re.first) == 0 || table[re.first] > cost)){
                        update = true;
                        table[re.first] = cost;
                }

            }
        }

        string t;
        cin >> t;

        cout << table[t] << endl;
    }

    return 0;
}

C++: #include <climits>
#include <cstdlib>
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;

template<class T> inline void chmin(T &a, const T &b) { if(a > b) a = b; }

typedef vector<vector<int>> graph;

void dfs(int v, const graph &G, vector<bool> &visited, vector<int> &order) {
	visited[v] = true;
	for(const auto &to : G[v]) {
		if(!visited[to]) dfs(to, G, visited, order);
	}
	order.emplace_back(v);
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	for(int n; cin >> n && n;) {
		unordered_map<string, int> encoder;
		vector<int> price(n);

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

		int m;
		cin >> m;

		graph G(n);
		for(int i = 0; i < m; ++i) {
			string target;
			int k;
			cin >> target >> k;

			const int to = encoder[target];
			for(int j = 0; j < k; ++j) {
				string from;
				cin >> from;
				G[encoder[from]].emplace_back(to);
			}
		}

		vector<bool> visited(n, false);
		vector<int> order;
		for(int v = 0; v < n; ++v) {
			if(!visited[v]) dfs(v, G, visited, order);
		}

		vector<int> sum(n, INT_MAX);
		for(int i = n - 1; i >= 0; --i) {
			const int v = order[i];
			chmin(sum[v], price[v]);

			for(const auto &to : G[v]) {
				if(sum[to] == INT_MAX) sum[to] = 0;
				sum[to] += sum[v];
			}
		}

		string want;
		cin >> want;
		cout << sum[encoder[want]] << endl;
	}

	return EXIT_SUCCESS;
}

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

struct item
{
  std::vector<std::string> materials;
  int price = 0;
  int true_price = -1;
  item(int price) : price(price){};
};

int calc_cost (std::unordered_map<std::string, item>& items, const std::string& name) {
  auto& target = items.at(name);
  if ( target.true_price != -1 )
    return target.true_price;

  if ( target.materials.empty() ){
    target.true_price = target.price;
    return target.true_price;
  }
  
  int sum_of_price = 0;
  for(const std::string& material : target.materials){
    sum_of_price += calc_cost(items, material);
  }

  return target.true_price = std::min(target.price, sum_of_price);
}

int main(){
  while(true) {
    std::unordered_map<std::string, item> items;
    int N;

    std::cin >> N;
    if (N == 0)
      break;

    for(int i = 0; i < N; ++i) {
      std::string name;
      int price;
      std::cin >> name >> price;
      items.insert({name, price});
    }

    std::cin >> N;
    for(int i = 0; i < N; ++i){
      std::string name;
      std::cin >> name;

      int M;
      std::cin >> M;
      std::vector<std::string> materials(M);
      for(int j = 0; j < M; ++j){
        std::string mat_name;
        std::cin >> mat_name;
        materials.at(j) = mat_name;
      }

      items.at(name).materials = materials;
    }

    std::string name;
    std::cin >> name;
    std::cout << calc_cost(items, name) << std::endl;
  }
}

C++: #include "bits/stdc++.h"

using namespace std;

typedef pair<int,int> pii;
typedef vector<int> vi;

#define dump(x)  cerr << #x << " = " << (x) << endl
#define rep(i,n) for(int i=0;i<(n);i++)
#define all(a)  (a).begin(),(a).end()
#define pb push_back
#define INF (999999999/2)
map< string,vector<string> > pas;
map<string,int> mp;

int dfs(string s){
    int ret=0;
    if(pas.find(s)==pas.end()){
        return mp[s];
    }
    else{
        rep(i,pas[s].size()){
            ret+=dfs(pas[s][i]);
        }
    }
    return min(ret,mp[s]);
}

int main(){
    int n,m;
    while(cin>>n&&n){
        pas.clear();
        mp.clear();
        rep(i,n){
            string s;
            int a;
            cin>>s>>a;
            mp[s]=a;
        }
        cin>>m;
        rep(i,m){
            string s;
            cin>>s;
            int k;
            cin>>k;
            rep(j,k){
                string x;
                cin>>x;
                pas[s].pb(x);
            }
        }
        string a;
        cin>>a;
        int sum=dfs(a);
        cout<<sum<<endl;
    }
}