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 <stdio.h>
#include <string.h>

int n;

struct item{
    char name[256];
    int cost;
    char used[100][256];
    int size;
} ;

item list[100];
int memo[100];

int getCost(int vertex)
{
    if(memo[vertex]!=-1)return memo[vertex];
    int i, j;
    int ans;
    
    if (list[vertex].size == 0){
        return (list[vertex].cost);
    }
    else {
        ans = 0;
        for (i = 0; i < list[vertex].size; i++){
            for (j = 0; j < n; j++){
                if (strcmp(list[vertex].used[i], list[j].name) == 0){
                    ans += getCost(j);
                }
            }
        }
        list[vertex].cost = list[vertex].cost > ans ? ans : list[vertex].cost;
    }
    return (list[vertex].cost);
}

int main(void)
{
    int i, j, k;
    int m, kk;
    char key[256], temp[256];
    int look, sum;
    
    while (1){
        scanf("%d", &n);
        
        if (n == 0){
            break;
        }
        for(i=0;i<n;i++)memo[i]=-1;
        for (i = 0; i < n; i++){
            scanf("%s%d", list[i].name, &list[i].cost);
            list[i].size = 0;
        }
        
        scanf("%d", &m);
        for (i = 0; i < m; i++){
            scanf("%s", key);
            for (j = 0; j < n; j++){
                if (strcmp(key, list[j].name) == 0){
                    look = j;
                }
            }
            scanf("%d", &kk);
            list[look].size = kk;
            for (j = 0; j < kk; j++){
                scanf("%s", temp);
                for (k = 0; k < n; k++){
                    if (strcmp(temp, list[k].name) == 0){
                        strcpy(list[look].used[j], temp);
                    }
                }
            }
        }
        scanf("%s", key);
        for (j = 0; j < n; j++){
            if (strcmp(key, list[j].name) == 0){
                look = j;
            }
        }
        
        printf("%d\n", getCost(look));
        
    }
    
    return (0);
}

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

using namespace std;

map<string, int> value;
map<string, vector<string> > recip;


int rennkinn(string& obj)
{
	int sum = value[obj];
	
	if( recip.find(obj) != recip.end() ) {

		vector<string>& parts = recip.find(obj)->second;

		int tmp = 0;
		for( auto& p : parts ) {
			tmp += rennkinn(p);
		}

		if( tmp < sum )
			sum = tmp;		
	}

	return sum;
}

int main(int argc, char* argv[])
{
	while(1) {

		int np;
		cin >> np;
		if( np == 0 )
			break;
	
		for( int i = 0; i < np; i++ ) {
			string p;
			cin >> p;
			int v;
			cin >> v;
			value[p] = v;
		}

		int nr;
		cin >> nr;
		for( int i = 0; i < nr; i++ ) {
			string p;
			cin >> p;
			int np;
			cin >> np;
			vector<string> ps;
			for( int j = 0; j < np; j++ ) {
				string p;
				cin >> p;
				ps.push_back(p);
			}
			recip[p] = ps;
		}


		string obj;
		cin >> obj;

		cout << rennkinn(obj) << endl;
		
		value.clear();
		recip.clear();
	}
	

    return 0;
}

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

using namespace std;

vector<string> item;
vector<int> cost;
vector<vector<string> > list;

map<string,int> name;

int saiki(int n){
	int cont=0;
	
	if(list[n].empty()==1){
		return cost[n];
	}
	
	for(int i=0;i<list[n].size();i++){
		cont+=saiki(name[list[n][i]]);
	}
	
	return min(cont,cost[n]);
}
int main(){
	while(1){
		int n;
		cin>>n;
		if(n==0){
			break;
		}
		item.clear();
		cost.clear();
		list.clear();
		for(int i=0;i<n;i++){
			string a;
			int b;
			cin>>a>>b;
			item.push_back(a);
			cost.push_back(b);
			name[a]=i;
		}
		int m;
		cin>>m;
		for(int i=0;i<n;i++){
			vector<string> kari;
			list.push_back(kari);
		}
		for(int i=0;i<m;i++){
			string a;
			int b;
			cin>>a>>b;
			vector<string> kari;
			kari.clear();
			for(int j=0;j<b;j++){
				string c;
				cin>>c;
				kari.push_back(c);
			}
			list[name[a]]=kari;
		}
		
		string a;
		cin>>a;
		cout<<saiki(name[a])<<endl;;
	}
}

C++: #include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define SIZE 102

using namespace std;

void Inputdate(void);             //データ入力
void Solve(void);                 //データ処理と出力

int  n,m;
int  sum;                         //合計値
int  Price[SIZE];                 //素材の値段  
int  Quantity[SIZE];              //練金時に必要な素材の種類の数        
char Item[SIZE][SIZE];            //素材の名前
char Recipe[SIZE][SIZE];          //練金の結果
char Material[SIZE][SIZE][SIZE];  //練金に必要な素材
char Favorite[SIZE];              //最終練金結果

int main(){
  
  int  i,j;
  
  while(1){
   
    scanf("%d",&n);

    if(n==0){
      break;
    } 

    /*データの入力*/
    Inputdate();
    
    /*データ処理と出力*/
    Solve();
    
  }

  return 0;
}
void Inputdate(void){

  int  i,j;
  
  /*素材とその値段の入力*/
  
  for(i=0;i<n;i++){
    scanf("%s %d",Item[i],&Price[i]);
  }

  /*練金レシピの入力*/
  
  scanf("%d",&m);  //レシピ数の入力
  
  for(i=0;i<m;i++){
    
    scanf("%s %d",Recipe[i],&Quantity[i]);
    
    for(j=0;j<Quantity[i];j++){
      scanf("%s",Material[i][j]);
    }
    
  }
  
  /*最終練金結果の出力*/
  
  scanf("%s",Favorite);
  
  return;
  
}
void Solve(void){
  
  int i,j,k;
  int Total_Price=0;        //練金にかかった値段
  int Usual_Price=0;        //練金結果の通常価格
  
  /*レシピ数だけ繰り返す*/
  
  for(i=0;i<m;i++){
    
    /*最終でない練金結果の通常価格を探す*/
    
    j=0;
    while(strcmp(Item[j-1],Recipe[i])!=0){
      Usual_Price=Price[j];
      j++;
    }
    
    /*練金にかかる値段を調べる*/
    
    for(j=0;j<Quantity[i];j++){
      for(k=0;k<n;k++){
	if(strcmp(Item[k],Material[i][j])==0){
	  Total_Price+=Price[k];
	  k=n;
	}
      }
    }
    
    /*元値と練金後の価格を比較*/
    
    if(Total_Price<=Usual_Price){
      for(k=0;k<n;k++){
	if(strcmp(Item[k],Recipe[i])==0){
      Price[k]=Total_Price;
      k=n;
      }
    }
    } 
    
    Total_Price=0;
  }


  for(i=0;i<n;i++){
    printf("%s %d\n",Item[i],Price[i]);
  }

  /*最終練金結果の価格を調べる*/

  for(i=0;i<n;i++){
    if(strcmp(Favorite,Item[i])==0){
      printf("%d\n",Price[i]);
      break;
    }
  }

  return;
}

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

int main(){
	int n , m , p , psum;
	string a , b;
	string want;
	map<string , int> item;
	while(cin >> n , n){
		for(int i=0;i<n;++i){
			cin >> a >> p ;
			item.insert(map<string , int>::value_type( a , p ));
		}
		cin >> m;
		for(int i=0;i<m;++i){
			psum=0;
			cin >> a >> p; //??¬??????a ???????????°p
			for(int j=0 ; j<p ;++j){
				cin >> b;  //??¬??????
				if(item.find(b)!=item.end()) psum+=item[b];
			}
				if(psum < item[a]) {
					item[a]=psum;//???????????´
				}
		}
		cin >> want;
		cout << item[want] << endl;
	}	
	return 0;
}