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>

using namespace std;

#define INF 1 << 10

int main() {
	int n;

	while (cin >> n, n++) {
		map<string, int> items;
		int prices[101];
		fill(&prices[0], &prices[0]+101, INF);

		for (int i = 1; i < n; ++i) {
			string name; cin >> name;
			int price; cin >> price;
			items[name] = i;
			prices[i] = price;
		}

		int m; cin >> m;
		vector< vector< vector<int> > > recipes(n);
		for (int i = 0; i < m; ++i) {
			string o; cin >> o;
			int k; cin >> k;

			vector<int> v;
			for (int j = 0; j < k; ++j) {
				string name; cin >> name;
				v.push_back(items[name]);
			}
			recipes[items[o]].push_back(v);
		}

		while (1) {
			bool update = false;

			for (int i = 1; i < n; ++i) {
				for (int j = 0; j < recipes[i].size(); ++j) {
					int price = 0;
					for (int k = 0; k < recipes[i][j].size(); ++k)
						price += prices[recipes[i][j][k]];

					if (price < prices[i]) prices[i] = price, update = true;
				}
			}

			if (!update) break;
		}

		string query; cin >> query;
		cout << prices[items[query]] << endl;
	}
}

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

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

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]には材料の数

		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];
			}
		}

		while(true){
			bool update = false;
			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]];
				}
				if(price < items[r[i].index]){
					items[r[i].index] = price;
					update = true;
				}
			}
			if(!update)break;
		}

		std::string want;
		std::cin >> want;
		std::cout << items[indexes[want]] << std::endl;
	}
}

C++: #include <bits/stdc++.h>

using namespace std;

#define MAX 200
#define INF INT_MAX
typedef pair<string,int> P;
typedef vector<string> Vec;

int N;
vector<P> vec;

int cost(Vec v){
  int res = 0;
  for(int i = 0 ; i < (int)v.size() ; i++){
    for(int j = 0 ; j < N ; j++){
      if(vec[j].first == v[i]){
        res += vec[j].second;
        break;
      }
    }
  }
  return res;
}

int main(){
  int M, K;

  while(cin >> N, N){
    map<string,Vec> mp;
    P in; 

    vec.clear();
    for(int i = 0 ; i < N ; i++){
      cin >> in.first >> in.second;
      vec.push_back(in);
    }

    string str, s, item;
    cin >> M;
    for(int i = 0 ; i < M ; i++){
      cin >> str >> K;
      for(int j = 0 ; j < K ; j++){
        cin >> s;
        mp[str].push_back(s);
      }
    }    

    map<string,Vec>::iterator it;
    for(int i = 0 ; i < 3 ; i++){
      for(it = mp.begin() ; it != mp.end() ; ++it){
        for(int j = 0 ; j < N ; j++){
          if(vec[j].first == it->first){
            vec[j].second = min(vec[j].second, cost(it->second));
          }
        }
      }
    }
    cin >> item;
    int ans = INF;
    for(int i = 0 ; i < N ; i++){
      if(vec[i].first == item){
        ans = vec[i].second;
        break;
      }
    }
  
    cout << ans << endl;
  }

  return 0;
}

C++: #include<stdio.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<string.h>
#include<map>
#include<queue>

using namespace std;

typedef pair<int,int> pii;

#define rep(i,j) for(int i=0;i<(j);i++)
#define reps(i,j,k) for(int i=j;i<=k;i++)
#define in(i,j,k) ((i)>=(j)&&(i)<=(k))


int main(){
	map<string,int> m;
	map<string,vector<string> > l;
	vector<string> str;
	int n,v,t;
	string s,u;
	for(;;){
		cin >> n;
		if(!n)break;
		m.clear();
		l.clear();
		while(n--){
			cin >> s >> v;
			m[s]=v;
		}
		cin >> n;
		while(n--){
			cin >> s >> t;
			str.push_back(s);
			v=0;
			while(t--){
				cin >> u;
				l[s].push_back(u);
			}
		}
		t=1;
		while(t){
			t=0;
			rep(i,str.size()){
				v=0;
				rep(j,l[str[i]].size())v += m[l[str[i]][j]];
				if(m[str[i]]<v){
					m[str[i]]=v;
					t=1;
				}
			}
		}
		cin >> s;
		cout << m[s] << endl;
	}
	
	return 0;
}

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

using namespace std;

map<string,int> item;

const int INF = 2000000000;

class Recipe{
public:
	string To;
	vector<string> From;
	int GetCost(){
		if(From.size() == 0){
			return INF;
		}
		int c = 0;
		vector<string>::iterator it;
		for(it = From.begin();it<From.end();it++){
			c += item[*it];
		}
		return c;
	}
};


map<string,Recipe> recipe;



int itemn;
int recipen;

int main(){
	int self;
	char str[256];
	while(scanf("%d",&itemn) != EOF){
		if(itemn == 0){break;}
		//printf("CASE\n");
		item.clear();
		recipe.clear();
		//printf("ITEMS %d:\n",itemn);
		for(int i=0;i<itemn;i++){
			scanf("%s %d",str,&self);
			item[str] = self;
			//printf("%s	%d\n",str,self);
		}
		scanf("%d",&recipen);
	
		for(int i=0;i<recipen;i++){
			Recipe r;
			scanf("%s %d",str,&self);
			r.To = str;
			for(int j=0;j<self;j++){
				scanf("%s",str);
				r.From.push_back(str);
			}
			recipe[r.To] = r;
		}
		scanf("%s",str);
		
		//printf("TARGET:%s\n",str);
		printf("%d\n" , item[str] < recipe[str].GetCost() ? item[str] : recipe[str].GetCost() );
	}
	return 0;
}

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

typedef pair<int,string> pis;

int main() {
	int n;
	while(cin >> n, n) {
		vector<pis> v;
		for(int i = 0; i < n; i++) {
			string s;
			int c;
			cin >> s >> c;
			v.push_back(pis(c,s));
		}
		sort(v.begin(), v.end());

		int m;
		vector<vector<string> > r;
		cin >> m;
		for(int i = 0; i < m; i++) {
			int k;
			string s;
			cin >> s;
			cin >> k;
			r.push_back(vector<string>());
			r[i].push_back(s);
			for(int j = 0; j < k; j++) {
				cin >> s;
				r[i].push_back(s);
			}
		}

		for(int i = 0; i < v.size(); i++) {
			for(int j = 0; j < r.size(); j++) {
				if(v[i].second == r[j][0]) {
					int nc = 0;
					for(int k = 1; k < r[j].size(); k++) {
						for(int l = 0; l < v.size(); l++) {
							if(r[j][k] == v[l].second) {
								nc += v[l].first;
							}
						}
					}
					v[i].first = min(v[i].first, nc);
				}
			}
		}

		string want;
		cin >> want;
		for(int i = 0; i < v.size(); i++) {
			if(v[i].second == want) {
				cout << v[i].first << endl;
				break;
			}
		}
	}
}