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++){
      butu[i].sozai.clear();
      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 <stdio.h>
#include <queue>
#include <string.h>
using namespace std;
#define INT_MAX 4294967295;
typedef pair<int,int> P;

//howmuch[i]:i番のアイテムの最小の値段
int howmuch[100];

//itemname[i]:i番目のアイテムの名前
char itemname[100][101];

//n:アイテムの種類 m:レシピの数
int n,m;

//resipeuseditem[i][k]:iをつくるためにkを用いたかどうかの判定
bool resipeuseditem[100][100];

//resipeN[i]:iを作るために用いたアイテムの番号を保存する
queue <int> resipeN[100];

//allminseek作業用キュー
priority_queue< P,vector<P>,greater<P> > que;

//アイテム名を番号に変換する関数
int nameTOnonber(char *);

//最小値を求める
void allminseek();

int main()
{
	int k,i,j,oTOi,o2;
	char o[101];

	scanf("%d",&n);

	while(n != 0){
	//初期化
	for(i = 0; i < 100; i++){
		for(j = 0; j < 100; j++){
			resipeuseditem[i][j] = false;
		}
	}

	//入力
	for(i = 0;i < n; i++){
		fflush(stdin);
		scanf("%s %d",itemname[i],&howmuch[i]);
		int a = nameTOnonber(itemname[i]);
		que.push(P(howmuch[i],a));
	}

	scanf("%d",&m);
	for(i = 0;i < m; i++){
		scanf("%s %d",o,&k);
		oTOi = nameTOnonber(o);
		//printf("k:%d\n",k);
		for(j = 0; j < k; j++){
			scanf("%s",o);
			o2 = nameTOnonber(o);
			resipeN[oTOi].push(o2);
			resipeuseditem[oTOi][o2] = true;
			//printf("作るもの:%d 素材[%d]:%d\n",oTOi,j,o2);
		}
		//printf("size:%d\n",resipeN[oTOi].size());
	}
	
	//探索
	allminseek();

	scanf("%s",o);
	printf("%d\n",howmuch[ nameTOnonber(o) ]);

	scanf("%d",&n);
	}
	return 0;
}

int nameTOnonber(char *name){
	for(int i = 0; i < n; i++){
		if(strcmp(itemname[i],name) == 0){
			//printf("アイテム名:%s 配列番号:%d\n",name,i);
			return i;
		}
	}

	printf("nameTOnonber変換ミス\n");
	return INT_MAX;
}

void allminseek(){

	//アイテムiを使用したかどうかのフラグ
	bool used[100];
	int temp,minNO;

	//printf("min:配列%d 値段%d",min.first,min.second);
	for(int i = 0; i < n; i++)	used[i] = false;

	while(!que.empty()){
		minNO = que.top().second;
		que.pop();
		//printf("最小値段アイテム:%s\n",itemname[minNO]);
		if(!used[ minNO ]){
			//minNOを使用しているレシピの探索と実行
			for(int i = 0;i < n; i++){
				//printf("[%d][%d]%d\n",i,minNO,resipeuseditem[i][minNO]);
				if(resipeuseditem[i][minNO]){
					temp = 0;
					for(int j = 0; j < resipeN[i].size(); j++){
						temp += howmuch[ resipeN[i].front() ];
						//printf("材料:%d 値段:%d 合計:%d\n",resipeN[i].front(),howmuch[ resipeN[i].front() ],temp);
						resipeN[i].push(resipeN[i].front());
						resipeN[i].pop();
					}
					if(howmuch[i] > temp){
						howmuch[i] = temp;
						que.push(P(temp,i));
					}
				}
			}
			
			used[ minNO ] = true;
		}
	}
}

C++:     #include<iostream>  
    #include<map>  
    #include<vector>  
    using namespace std;  
      
    int main(){  
      
      int n, p, m, q;  
      string s, o, u;  
      map < string ,int > mp;  
      vector < string > vec;  
      
      while(cin >> n, n){  
      
        map < string ,int > mp;  
        vector < string > vec;  
          
        for(int i=0;i<n;i++){  
          cin >> s >> p;  
          mp[s] = p;  
          vec.push_back(s);  
        }  
      
        cin >> m;  
        for(int i=0;i<m;i++){  
          cin >> s >> p;  
      
          int k = 0;  
          for(int i=0;i<p;i++){  
        cin >> o;  
        k += mp[o];  
          }  
      
          mp[s] = min(mp[s], k);  
        }  
        cin >> s;  
        cout << mp[s] << 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;
			}
		}
	}
}