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<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<string>
using namespace std;
typedef struct{
  vector<string> sozai;
  long long money;
}BUTU;
pair<string,long long> P[1002];
BUTU butu[1024];
long long n,p,m,a,b;
string s,ss,mokuhyou;
long long tansaku(string now){
  for(int i=0;i<n;i++){
    if(P[i].first==now){
      return P[i].second;
    }
  }
  return -1;
}
long long check(string now){
  long long banti=tansaku(now);
  long long f=butu[banti].sozai.size();
  long long cnt=0;
  if(f==0){
    return butu[banti].money;
  }
  else{
    for(int i=0;i<f;i++){
      if(tansaku(butu[banti].sozai[i])!=-1){
	cnt+=check(butu[banti].sozai[i]);
      }
      else{
	return butu[banti].money;
      }
    }
    return min(cnt,butu[banti].money);
  }
  return -1;
}
main(){
  while(1){
    cin>>n;
    if(n==0)break;
    for(int i=0;i<n;i++){
      cin>>s>>p;
      butu[i].money=p;
      P[i].first=s;
      P[i].second=i;
    }
    cin>>m;
    for(int i=0;i<m;i++){
      cin>>s>>a;
      b=tansaku(s);
      for(int j=0;j<a;j++){
	cin>>ss;
	butu[b].sozai.push_back(ss);
      }
    }
    cin>>mokuhyou;
    cout<<check(mokuhyou)<<endl;
  }
}

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

using namespace std;

struct Item{
	string name;
	int price;
	int item_number;
	bool cook_flag;
};

struct Recipe{
	int item_number[100];
	int material;
};
Item item[100];
Recipe recipe[100];

int min(Item _item, int _num){
	if (!_item.cook_flag){
		return _item.price;
	}
	else{
		int sum = 0;
		for (int i = 0; i < recipe[_num].material; i++){
			int num = recipe[_num].item_number[i];
			int cook_price = min(item[num], num);
			if (cook_price > item[num].price) sum += item[num].price;
				else sum += cook_price;
		}
		if (sum > _item.price) sum = _item.price;
		return sum;
	}
}

int get_num(string name){
	for (int i = 0; i < 100; i++){
		if (name == item[i].name){
			return i;
		}
	}

}

int main(){
	while (1){
		int n;
		cin >> n;
		if (!n)break;
		for (int i = 0; i < n; i++){
			cin >> item[i].name;
			cin >> item[i].price;
			item[i].item_number = i;
			item[i].cook_flag = false;
		}

		int m;
		cin >> m;
		string o;
		int k;
		for (int i = 0; i < m; i++){
			cin >> o;
			int o_num = get_num(o);
			item[o_num].cook_flag = true;
			cin >> k;
			recipe[o_num].material = k;

			for (int j = 0; j < k; j++){
				string name;
				cin >> name;
				int num = get_num(name);
				recipe[o_num].item_number[j] = num;
			}
		}

		string req;
		cin >> req;
		int num = get_num(req);
		int ans;
		ans = min(item[num], num);
		cout << ans<<"\n";
	}
	return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
using namespace std;
pair<string, int>X[1000];
vector<int>Y[1000];
int dp[1000];
int N, M, C, Q; string S;
int main() {
	while (true) {
		for (int i = 0; i < 1000; i++) {
			dp[i] = 0;
			Y[i].clear();
			X[i] = make_pair("", 0);
		}
		cin >> N;
		if (N == 0) { break; }
		for (int i = 0; i < N; i++) {
			cin >> X[i].first >> X[i].second;
			dp[i] = X[i].second;
		}
		cin >> M;
		for (int i = 0; i < M; i++) {
			cin >> S;
			for (int j = 0; j < N; j++) {
				if (S == X[j].first) {
					C = j;
				}
			}
			cin >> Q;
			for (int j = 0; j < Q; j++) {
				cin >> S;
				for (int k = 0; k < N; k++) {
					if (X[k].first == S) {
						Y[C].push_back(k);
					}
				}
			}
		}
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				int sum = 0;
				if(Y[j].size()==0){
					continue;
				}
				for (int k = 0; k < Y[j].size(); k++) {
					sum += X[Y[j][k]].second;
				}
				if (dp[j] > sum) {
					dp[j] = sum;
				}
			}
		}
		cin >> S;
		for (int i = 0; i < N; i++) {
			if (S == X[i].first) {
				C = i;
			}
		}
		cout << dp[C] << endl;
	}
	return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <string>
#include <bitset>
using namespace std;
#define rep(I,N) for(int I = 0; I < (int)(N); I++)
#define FIN(V) cout<<V<<endl
#define pb push_back
#define INF (1 << 30)
typedef pair<int, int> P;
typedef long long ll;
typedef priority_queue<int> pq;
int StrToInt(string);
string IntToStr(int);
int solve(map<string, int> list, map<string, vector<string> > lesp, string make){
	vector<string> item = lesp[make];
	ll mini = INF;
	ll cost = 0;
	rep(i, item.size()){
		if(!lesp[item[i]].empty()){
			//cout << "item" << endl;
			cost += solve(list, lesp, item[i]);
		}else{
			cost += list[item[i]];
		}
	}
	mini = min(mini, cost);
	return mini;
}

int main(void){
	int n, m;
	while(cin >> n, n){
		map<string, int> LIST;
		string MAKE;
		rep(i, n){
			string s;
			int cost;
			cin >> s >> cost;
			LIST[s] = cost;
		}
		cin >> m;
		map<string, vector<string> > LESP;
		rep(i, m){
			string s;
			cin >> s;
			int num;
			cin >> num;
			vector<string> v;
			rep(j, num){
				string L;
				cin >> L;
				v.push_back(L);
			}
			LESP[s] = v;
		}
		cin >> MAKE;
		if(m == 0){
			cout << LIST[MAKE] << endl;
			continue;
		}
		ll ans = solve(LIST, LESP, MAKE);
		FIN(ans);

	}


	return 0;
}



int StrToInt(string s){
	stringstream ss;
	ss << s;
	int val;
	ss >> val;
	return val;
}
string IntToStr(int i){
	stringstream ss;
	ss << i;
	return ss.str();
}

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

#define REP(i,n) for(int i = (int)(n) - 1; i >= 0; --i)

using namespace std;

int costs[101];
vector<int> recipe[101];
bool flags[101];

int getCost(int goal){
	if(recipe[goal].empty()) return costs[goal];
	flags[goal] = true;
	int sum = 0;
	REP(i, recipe[goal].size()){
		if(flags[recipe[goal][i]]){
			flags[goal] = false;
			return costs[goal];
		}
		sum += getCost(recipe[goal][i]);
	}
	flags[goal] = false;
	if(sum < costs[goal]){
		return sum;
	}else{
		return costs[goal];
	}
}

int main(){
	int n, m;
	while(true){
		cin >> n;
		if(n==0)break;
		
		memset(flags, 0, sizeof(flags));

		map<string,int> hash;
		
		REP(i,n){
			string name;
			cin >> name >> costs[i];
			hash.insert(map<string,int>::value_type(name,i));
			recipe[i].clear();
		}

		cin >> m;
		REP(i, m){
			string name;
			int item;
			int num;
			cin >> name >> num;
			item = hash[name];
			recipe[item].reserve(num);
			REP(j, num){
				string mate;
				int mat;
				cin >> mate;
				mat = hash[mate];
				recipe[item].push_back(mat);
			}
		}

		string goalName;
		int goal;
		cin >> goalName;
		goal = hash[goalName];

		cout << getCost(goal) << endl;
		
	}
	
	return 0;
}