Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
		"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))
	}
}

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 main()
{
	int n;
	while( cin >> n && n ){
		int id = 0;
		map< string, int > nameList;
		vector< long long int > valueList( n, 0 );
		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( n, vector< int >() );
		cin >> m;
		for( int i = 0; i < m; ++i ){
			string o;
			int k;
			cin >> o >> k;
			int productId = nameList.find( o )->second;
			for( int j = 0; j < k; ++j ){
				string q;
				cin >> q;
				int materialId = nameList.find( q )->second;
				recipeList[ productId ].push_back( materialId );
			}
		}
		vector< int > depthList( n, -1 );
		queue< int > updateList;
		for( int i = 0; i < n; ++i ){
			updateList.push( i );
		}
		while( !updateList.empty() ){
			int id = updateList.front();
			updateList.pop();
			if( recipeList[ id ].empty() ){
				depthList[ id ] = 0;
				continue;
			}
			int size = recipeList[ id ].size();
			int d = -1;
			for( int i = 0; i < size; ++i ){
				d = max( d, depthList[ recipeList[ id ][ i ] ] );
			}
			if( d > -1 ){
				depthList[ id ] = d + 1;
			}else{
				updateList.push( id );
			}
		}
		vector< pair< int, int > > sortedList;
		for( int i = 0; i < n; ++i ){
			sortedList.push_back( make_pair( depthList[ i ], i ) );
		}
		sort( sortedList.begin(), sortedList.end() );

		for( int i = 0; i < (int)sortedList.size(); ++i ){
			int id = sortedList[ i ].second;
			vector< int > recipe = recipeList[ id ];
			if( recipe.empty() ){
				continue;
			}
			long long int value = 0;
			for( int j = 0; j < (int)recipe.size(); ++j ){
				value += valueList[ recipe[ j ] ];
			}
			if( value < valueList[ id ] ){
				valueList[ id ] = value;
			}
		}

		string ansName;
		cin >> ansName;
		cout << valueList[ nameList.find( ansName )->second ] << endl;
	}
	return 0;
}

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

map<string,int> normal;
map<string,vector<string> > rec;

int f(string x){
	int ans = normal[x] , sum = 0;
	if( rec[x].size() == 0 ) return ans;
	for(int i = 0 ; i < rec[x].size() ; i++){
		sum += f(rec[x][i]);
	}
	return min(ans,sum);
}

int main(){
	int n;
	while(cin >> n && n){
		for(int i = 0 ; i < n ; i++){
			string a;
			int b;
			cin >> a >> b;
			normal[a] = b;
		}
		int m;
		cin >> m;
		for(int i = 0 ; i < m ; i++){
			string x,y;
			cin >> x;
			int t;
			cin >> t;
			for(int j = 0 ; j < t ; j++){
				cin >> y;
				rec[x].push_back(y);
			}
		}
		string want;
		cin >> want;
		cout << f(want) << endl;
	}
}

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

using namespace std;
typedef unsigned long long ULL;

struct Dict {
    map<string,int> dict;
    int id;
    Dict() : id(0) {}

    int get(const string &name) {
        if(dict.count(name)) return dict[name];
        return dict[name] = id++;
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while(true) {
        int N;
        cin >> N;
        if(!N) break;

        Dict dict;
        vector<ULL> price(N);
        vector<vector<int> > materials(N);
        for(int i = 0; i < N; ++i) {
            string name;
            int p;
            cin >> name >> p;
            price[dict.get(name)] = p;
        }
        int M;
        cin >> M;
        for(int i = 0; i < M; ++i) {
            string to;
            cin >> to;
            const int to_id = dict.get(to);
            int cnt;
            cin >> cnt;
            while(cnt--) {
                string material;
                cin >> material;
                materials[to_id].push_back(dict.get(material));
            }
        }
        vector<ULL> memo(price);
        while(true) {
            bool updated = false;
            for(int i = 0; i < N; ++i) {
                const vector<int> &list = materials[i];
                if(list.size() == 0) continue;
                ULL acc = 0;
                for(vector<int>::const_iterator it = list.begin(); it != list.end(); ++it) {
                    acc += memo[*it];
                }
                if(acc < memo[i]) {
                    memo[i] = acc;
                    updated = true;
                }
            }
            if(!updated) break;
        }
        string target;
        cin >> target;
        cout << memo[dict.get(target)] << endl;
    }
    return 0;
}

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

using namespace std;

class recipe{
public:
	vector<string> src;
	string dst;
	int num;
};

int main(void){
	int n;
	
	while(cin >> n && n){
		int k;
		map<string,int> m;
		vector<recipe> rs;
		string str;
		
		int tmp;
		for(int i=0;i<n;i++){
			cin >> str >> tmp;
			m[str] = tmp;
		}
		cin >> n;
		for(int i=0;i<n;i++){
			recipe r;
			cin >> str;
			r.dst = str;
			cin >> k;
			r.num = k;
			for(int i=0;i<k;i++){
				cin >> str;
				r.src.push_back(str);
			}
			rs.push_back(r);
		}
		
		bool ended = false;
		while(!ended){
			ended = true;
			for(int i=0;i<rs.size();i++){
				tmp = 0;
				cout << rs[i].num << endl;
				for(int j=0;j<rs[i].num;j++){
					tmp += m[rs[i].src[j]];
				}
				if(m[rs[i].dst] > tmp){
					ended = false;
					m[rs[i].dst] = tmp;
				}
			}
		}
		cin >> str;
		cout << m[str] << endl;
	}
}

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


int n, m, k, p;
std::string s, o;
std::map<std::string, int> mp;

int main(){
    while(std::cin >> n){
        if(n == 0) break;

        for(int i = 0; i < n; i++){
            std::cin >> s >> p;

            mp[s] = p;
        }

        std::cin >> m;
        for(int i = 0; i < m; i++){
            std::cin >> o >> k;

            int tmp = 0;
            for(int j = 0; j < k; j++){
                std::cin >> s;
                tmp += mp[s];
            }
            mp[o] = std::min(mp[o], tmp);
        }

        std::cin >> s;
        std::cout << mp[s] << std::endl;
    }

    return 0;
}