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 <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <queue>
#include <map>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1<<30;

map<string, int> mp;
map<string, vector<string> > mp2;

int solve(string s) {
  if (mp2.count(s)) {
    int a = 0;
    FOR(it, mp2[s])
      a += solve(*it);
    return min(a, mp[s]);
  }
  return mp[s];
}

int main() {
  int n;
  while(cin>>n, n) {
    mp.clear();
    REP(i,n) {
      string s;
      int p;
      cin >> s >> p;
      mp[s] = p;
    }
    int m;
    cin >> m;
    mp2.clear();
    REP(i,m) {
      string s;
      int k;
      cin >> s >> k;
      vector<string> v;
      REP(j,k) {
        string t;
        cin >> t;
        v.push_back(t);
      }
      mp2[s] = v;
    }
    string s;
    cin >> s;
    cout << solve(s) << endl;
  }
}

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

class UnionFind{
public:
	int size;
	std::vector<int> par, rank;
	UnionFind();
	UnionFind(int _size);
	int find(int x);
	bool same(int x, int y);
	void unite(int x, int y);
};

UnionFind::UnionFind()
	:size(0), par(0), rank(0){}

UnionFind::UnionFind(int _size)
	:size(_size), par(_size), rank(_size){
	for(int i=0;i<size;i++){
		par[i] = i;
		rank[i] = 0;
	}
}

int UnionFind::find(int x){
	if(x == par[x]){
		return x;
	}
	return par[x] = find(par[x]);
}

bool UnionFind::same(int x, int y){
	return find(x) == find(y);
}

void UnionFind::unite(int x, int y){
	x = find(x);
	y = find(y);

	if(x == y)return;

	if(rank[x] < rank[y]){
		par[x] = par[y];
	}else{
		par[y] = par[x];
		if(rank[x] == rank[y]){
			rank[x]++;
		}
	}
}

struct Recipe{
	int index, stuff[100], size;
};

UnionFind uf;

bool comp(const Recipe& l_recipe, const Recipe& r_recipe){
	if(uf.same(l_recipe.index, r_recipe.index)){
		return uf.rank[l_recipe.index] > uf.rank[r_recipe.index];
	}
	return l_recipe.index < r_recipe.index;
}

int main(){
	int n;
	while(std::cin >> n, n){
		std::map<std::string, int> indexes;
		int items[100];//items[index]: index番目の値段
		for(int i=0;i<n;i++){
			std::string name;
			int price;
			std::cin >> name >> price;
			indexes[name] = i;
			items[i] = price;
		}
		Recipe r[100];//recipe[n][0]には材料の数
		uf = UnionFind(100);

		int m;
		std::cin >> m;
		for(int i=0;i<m;i++){
			std::string name;
			int stuff_n;
			std::cin >> name >> stuff_n;

			r[i].size = stuff_n;
			r[i].index = indexes[name];

			for(int j=0;j<stuff_n;j++){
				std::string stuff;
				std::cin >> stuff;
				r[i].stuff[j] = indexes[stuff];
				uf.unite(indexes[name], indexes[stuff]);
			}
		}
	
		std::sort(r, r+m, comp);

		for(int i=0;i<m;i++){
			int price = 0;
			for(int j=0;j<r[i].size;j++){
				price += items[r[i].stuff[j]];
			}
			items[r[i].index] = std::min(items[r[i].index], price);
		}
	
		std::string want;
		std::cin >> want;
		std::cout << items[indexes[want]] << std::endl;
	}
}

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

using namespace std;

void solve()
{
	int n;
	while (cin >> n, n)
	{
		map<string, int> table;
		for (int i = 0; i < n; ++i)
		{
			string name;
			int cost;
			cin >> name >> cost;
			table[name] = cost;
		}
		int m;
		cin >> m;
		for (int i = 0; i < m; ++i)
		{
			string name;
			int num;
			cin >> name >> num;
			int sum = 0;
			for (int j = 0; j < num; ++j)
			{
				string material;
				cin >> material;
				sum += table[material];
			}
			table[name] = min(table[name], sum);
		}
		string name;
		cin >> name;
		cout << table[name] << endl;
	}
}

int main()
{
	solve();
	return(0);
}

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

int main()
{
    std::map<std::string, int> ItemData;
    int Item_num;
    
    while (std::cin >> Item_num) {
        if (Item_num == 0) break;
        
        
        for (int i = 0; i < Item_num; ++i) {
            std::string ItemName;
            int ItemPrice;
            
            std::cin >> ItemName >> ItemPrice;
            ItemData[ItemName] = ItemPrice;
        }
        
        int mix_num;
        
        std::cin >> mix_num;
        
        for (int i = 0; i < mix_num; ++i) {
            std::string ItemName;
            int Material_num;
            
            std::cin >> ItemName >> Material_num;
            
            int temp = 0;
            std::string MaterialName;

            for (int j = 0; j < Material_num; ++j) {
                std::cin >> MaterialName;
                temp += ItemData[MaterialName];
            }
                
            ItemData[ItemName] = std::min(ItemData[ItemName], temp);
        }
        
        std::string Material;
        
        std::cin >> Material;
        
        std::cout << ItemData[Material] << std::endl;
    }
    
    return 0;
}

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

int main() {
    int n;
    while (cin >> n, n) {
        string i; int p;
        map<string, int> price;
        for (int j=0; j<n; ++j) {
            cin >> i >> p;
            price[i] = p;
        }
        int m;
        cin >> m;
        vector<vector<string>> recipe(m);
        string o, q; int k;
        for (int j=0; j<m; ++j) {
            cin >> o;
            recipe[j].push_back(o);
            cin >> k;
            for (int l=0; l<k; ++l) {
                cin >> q;
                recipe[j].push_back(q);
            }
        }
        for (int j=0; j<m; ++j) {
            for (int l=0; l<m; ++l) {
                int new_price = 0;
                for (int kk=1; kk<(int)recipe[l].size(); ++kk) {
                    new_price += price[recipe[l][kk]];
                }
                price[recipe[l][0]] = min(price[recipe[l][0]], new_price);
            }
        }
        string name;
        cin >> name;
        cout << price[name] << endl;
    }
    return 0;
}

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

string name[100];
string buy;
map<string, int> list;
int n,m;

int main(){
	while(true){

		cin >> n;
		if(!n)
			return 0;
		list.clear();

		for(int i=0; i<n; i++){
			cin >> name[i];
			cin >> list[name[i]];
		}

		cin >> m;
		for(int i=0; i<m; i++){
			int tmp;
			int price = 0;
			string temp;
			cin >> temp >> tmp;
			for(int k=0; k<tmp; k++){
				string s;
				cin >> s;
				price += list[s];
			}
			if(price < list[temp])
				list[temp] = price;
		}

		cin >> buy;
		cout << list[buy] << endl;
	}
}