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 <vector>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

int NUM_ITEM_MAX = 200;

long long int updateValue( int n, vector< long long int >& valueList, vector< vector< int > >& recipeList, vector< bool >& updatedList )
{
	if( updatedList[ n ] ){
		return valueList[ n ];
	}
	updatedList[ n ] = true;
	vector< int > recipe = recipeList[ n ];
	if( recipe.empty() ){
		return valueList[ n ];
	}
	long long int value = 0;
	for( int i = 0; i < (int)recipe.size(); ++i ){
		int id = recipe[ i ];
		value += updateValue( id, valueList, recipeList, updatedList );
	}
	if( value < valueList[ n ] ){
		valueList[ n ] = value;
	}
	return valueList[ n ];
}

int main()
{
	int n;
	while( cin >> n && n ){
		int id = 0;
		map< string, int > nameList;
		vector< long long int > valueList( NUM_ITEM_MAX + 1, 1LL << 62 );
		for( int i = 0; i < n; ++i ){
			string s;
			int v;
			cin >> s >> v;
			int d = id++;
			nameList.insert( make_pair( s, d ) );
			valueList[ d ] = v;
		}
		int m;
		vector< vector< int > > recipeList( NUM_ITEM_MAX + 1, vector< int >() );
		cin >> m;
		for( int i = 0; i < m; ++i ){
			string o;
			int k;
			cin >> o >> k;
			int count = nameList.count( o );
			if( count == 0 ){
				int d = id++;
				nameList.insert( make_pair( o, d ) );
			}
			int productId = nameList[ o ];
			for( int j = 0; j < k; ++j ){
				string q;
				cin >> q;
				count = nameList.count( q );
				if( count == 0 ){
					int d = id++;
					nameList.insert( make_pair( q, d ) );
				}
				int materialId = nameList[ q ];
				recipeList[ productId ].push_back( materialId );
			}
		}
		vector< bool > updatedList( nameList.size(), false );
		for( int i = 0; i < (int)nameList.size(); ++i ){
			updateValue( i, valueList, recipeList, updatedList );
		}

		string ansName;
		cin >> ansName;
		cout << valueList[ nameList[ ansName] ] << endl;
	}
	return 0;
}

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

int main()
{
	map<string,int> memo;
	int n;
	while(cin >> n){
		if(n==0)
			break;
		string str;
		int prise;
		for(int i=0;i<n;i++){
			cin >> str >> prise;
			memo[str] = prise;
		}
		int resipi;
		cin >> resipi;
		map<string,int> resi;
		int count;
		string o;
		for(int i=0;i<resipi;i++){
			cin >> str >> count;
			resi[str] = 0;
			for(int j=0;j<count;j++){
				cin >> o;
				resi[str] += memo[o];
			}
			if(resi[str] < memo[str])
				memo[str] = resi[str];
		}
		string final;
		cin >> final;
		cout << memo[final] << endl;
	}
	return 0;
}

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

#define reep(i,n,m) for(int i=n;i<m;i++)
#define rep(i,n) reep(i,0,n)

using namespace std;

map<string,int> name_id;
vector<int> recipe[100];
int price[100];

int solve(int x){
    
    int len = recipe[x].size();

    if(len==0){
        return price[x];
    }

    int ans=0;
    rep(i,len){
        ans += solve(recipe[x][i]);
    }
    //printf("%d->%d\n",x,price[x]);
    return min(ans, price[x]);
}

int main(){
    int n;
    while(cin >> n,n){
        rep(i,n){
            string name;
            int p;
            cin >> name >> p;
            name_id[name] = i;
            price[i] = p;
        }

        int m;
        cin >> m;
        
        rep(i,m){
            string name;
            int num;
            cin >> name >> num;
            int id = name_id[name];
            rep(k,num){
                string r;
                cin >> r;
                recipe[id].push_back(name_id[r]);
            }
        }

        string a;
        cin >> a;
        cout << solve(name_id[a]) << endl;
    }
    return 0;
}