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>
using namespace std;

struct Recipe;

struct Item {
  int buy_cost;
  Recipe* recipe;
  int calced_min_cost;

  void init() {
    recipe = NULL;
    calced_min_cost = -1;
  }

  bool is_calced() {
    return calced_min_cost != -1;
  }
};

struct Recipe {
  int n;
  Item* parts[100];
};

map<string, Item> imap;

int calc_min_cost_of(Item& item) {
  if (item.is_calced()) return item.calced_min_cost;
  if (item.recipe == NULL) return item.calced_min_cost = item.buy_cost;
  auto& recipe = *item.recipe;
  int gen_cost = 0;
  for (int i = 0; i < recipe.n; i++) {
    gen_cost += calc_min_cost_of(*recipe.parts[i]);
    if (gen_cost >= item.buy_cost) return item.calced_min_cost = item.buy_cost;
  }
  return item.calced_min_cost = gen_cost;
}

// buff
Recipe recipes[100];

int main() {
  int n;
  while (cin >> n, n) {
    for (int i = 0; i < n; i++) {
      string name;
      int buy_cost;
      cin >> name >> buy_cost;
      imap[name] = {buy_cost, NULL, -1};
    }

    int m;
    cin >> m;
    for (int i = 0; i < m; i++) {
      auto& recipe = recipes[i];

      string target_name;
      cin >> target_name >> recipe.n;
      imap[target_name].recipe = &recipe;
      
      for (int j = 0; j < recipe.n; j++) {
        string part_name;
        cin >> part_name;
        recipe.parts[j] = &imap[part_name];
      }
    }
    
    string name;
    cin >> name;
    cout << calc_min_cost_of(imap[name]) << endl;
  }
  return 0;
}

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

vector<string> recipe[101];
map<string,int> items;
map<string,int> links;

int check(string name){
  if(recipe[links[name]].size()<1)
    return items[name];
  int sum=0;
  for(int i=0;i<recipe[links[name]].size();i++)
    {
      sum+=check(recipe[links[name]][i]);
    }
  return min(items[name],sum);
}

int main()
{
  int n;
  for(;cin>>n,n;)
    {
      for(int i=0;i<101;i++)
	recipe[i].clear();	      
      items.clear();
      links.clear();
      
      for(int i=0;i<n;i++)
	{
	  int a;
	  string b;
	  cin>>b>>a;
	  items.insert(make_pair(b,a));
	  links.insert(make_pair(b,i));
	}
      int m;
      
      cin>>m;
      for(int i=0;i<m;i++)
	{
	  string o;
	  int k;
	  cin>>o>>k;
	  for(int j=0;j<k;j++)
	    {
	      string tmp;
	      cin>>tmp;
	      recipe[links[o]].push_back(tmp);
	    }
	}
      string iname;
      cin>>iname;
      cout<<check(iname)<<endl;
      
    }
}

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

using namespace std;

int main()
{
	for(;;)
	{
		string all_item[101][101];
		int item_price[101],item_num[100]={0};
		int item_flag[101]={0};
		int n,m,nm,i,j,k,l,o,y,d;
		
		cin >> n ;
		if(n==0)
			break;
		
		for(i=0;i<n;i++)
			cin >> all_item[i][0] >> item_price[i];
		
		cin >> m ;
		for(i=0;i<m;i++)
		{
			int s_price=0;
			string item;
			cin >> item >> nm ;
			
			for(j=0;j<n;j++)
				if(all_item[j][0]==item)
					break;
			
			for(k=0;k<nm;k++)
			{
				cin >> item ;
				for(y=0;y<n;y++)
				{
					if(item==all_item[y][0])
						break;
				}
				item_num[y]++;
				all_item[y][item_num[y]]=all_item[j][0];
				
				s_price+=item_price[y];
			}
			if(s_price<item_price[j])
			{
				int a;
				a=item_price[j]-s_price;
				item_price[j]=s_price;
				
				A:;
				
				for(o=1;o<=item_num[j];o++)
				{
					if(all_item[j][o]!="0")
					{
						for(int r=0;r<n;r++)
						{
							if(all_item[j][o]==all_item[r][0])
							{
//								cout << "mt_item:" << all_item[j][0] << "\nfinish_item:" << all_item[j][o] << endl;
								item_price[r]-=a;
								if(item_num[r]>0)
								{
									item_flag[r]=1;
								}
								all_item[j][o]="0";
								break;
							}
						}
					}
				}
				for(d=0;d<n;d++)
				{
					if(item_flag[d]==1)
					{
						item_flag[d]=0;
						j=d;
						goto A;
					}
				}
			}
		}
		string last;
		cin >> last ;
		for(i=0;i<n;i++)
		{
			if(all_item[i][0]==last)
			{
				cout << item_price[i] << endl;
				break;
			}
		}
	}
}

C++: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define EQ(a,b) (abs((a)-(b))<EPS)
int n,m;
struct item
{
	string name;
	int cost,size;
	vector<string> le;
};
item lis[100];
int cos[100];
int msearch(string s)
{
	for(int i=0;i<n;i++)
	{
		if(lis[i].name==s)return i;
	}
}
int getcost(int v)
{
	if(cos[v]!=-1)return cos[v];
	else
	{
		if(lis[v].size==0)return lis[v].cost;
		else
		{
			int ans=0;
			for(int i=0;i<lis[v].size;i++)
			{
				ans+=getcost(msearch(lis[v].le[i]));
			}
			cos[v]=ans;
			return ans;
		}
	}
}
int main()
{
	while(1)
	{
		fill(cos,cos+100,-1);
		cin >> n;
		if(n==0)break;
                string s;
		int c;
		for(int i=0;i<n;i++)
		{
			cin >> s >> c;
			lis[i].name=s;
			lis[i].cost=c;
			lis[i].size=0;
		}
		cin >> m;
		for(int i=0;i<m;i++)
		{
			int t,k;
			cin >> s;
			cin >> t;
			for(int j=0;j<t;j++)
			{
				string st;
				cin >> st;
				k=msearch(s);
				lis[k].le.pb(st);
			}
			lis[k].size=t;
		}
		string str;
		cin >> str;
		cout << getcost(msearch(str))<< endl;
	}
	return 0;
}