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 <utility>
#include <map>
#include <vector>
using namespace std;
typedef map<string, int> m;

m price;
map<string,vector<string> > renkin;
string p[100];

int main() {
  int n;
  int m;
  while(cin >> n) {
    if(n==0) break;
    for(int i=0;i<n;i++) {
      string name;
      int p;
      cin >> name >> p;
      price.insert( pair<string,int>(name,p) );
    }

    cin >> m;
    for(int i=0;i<m;i++) {
      int sozai;
      cin >> p[i] >> sozai;
      for(int k=0;k<sozai;k++) {
        string name;
        cin >> name;
        renkin[p[i]].push_back(name);
      }
    }

    bool update = true;
    while(update) {
      update = false;
      for(int i=0;i<m;i++) {
        int sum = 0;
        for(int j=0;j<renkin[p[i]].size();j++) {
          sum += price[renkin[p[i]][j]];
        }
        if(sum < price[p[i]]) {
          price[p[i]] = sum;
          update = true;
        }
      }
    }
    string str;
    cin >> str;
    cout << price[str] << endl;
    price.clear();
    renkin.clear();
  }
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#define mp make_pair
using namespace std;

map<string,vector<string> > recipe;
map<string,int>items;

int price(string item){
  if(recipe.find(item) != recipe.end()){
    int p=0;
    for(int i=0;i<recipe[item].size();i++)
      p+= price(recipe[item][i]);
    return min(p,items[item]);
  }
  else return items[item];
}

int main(){
  int n,m,k;
  while(true){
    cin>>n;
    if(!n)break;
    string name;
    int pr;
    for(int i=0;i<n;i++){
      cin>>name>>pr;
      items.insert(mp(name,pr));
    }
    cin>>m;
    for(int j=0;j<m;j++){
      cin>>name>>k;
      vector<string> material;
      string mat_name;
      for(int i=0;i<k;i++){
	cin>>mat_name;
	material.push_back(mat_name);
      }
      recipe.insert(mp(name,material));
    }
    cin>>name;
    cout<<price(name)<<endl;
  }
  return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
int main(){
  int n;
  map<string, int> items;
  string name;
  int value;
  
  while(cin >> n, n){
    items.clear();
    
    for(int i = 0 ; i < n ; i++){
      cin >> name >> value;
      items.insert(make_pair(name, value));
    }
    int m;
    int total;
    string names;
    cin >> n;
    for(int i = 0 ; i < n ; i++){
      total = 0;
      cin >> name;
      cin >> m;
      for(int j = 0 ; j < m ; j++){
	cin >> names;
	total += items[names];
      }
      items[name] = min(items[name], total);
    }
    cin >> name;
    cout << items[name] << endl;
  }
  return 0;
}

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

using namespace std;

map<string,int> dp;
map<string,int> buy;
map<string, vector<string> > reci;

const int INF = 1000000;

#define rep(i,a) for(int i=0; i<(a); i++)

int solve(string to){
  int ari = 0;
  rep(i,reci[to].size()){
    ari += solve(reci[to][i]);
  }
  if(ari == 0){
    ari = buy[to];
  }
  
  int rtn = min(ari, dp[to]);
  dp[to] = rtn;
  return rtn;
}


int main(){
  int n;
  while(cin >> n, n){
    rep(i,n){
      string str; int p;
      cin >> str >> p;
      buy[str] = p;
      dp[str] = INF;
    }
    int r; cin >> r;
    rep(i,r){
      string str; int m;
      cin >> str >> m;
      rep(j,m){
	string ing;
	cin >> ing;
	reci[str].push_back(ing);
      }
    }

    // solve

    string to; cin >> to;
    cout << solve(to) << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#define INF 999999999
using namespace std;
std::map<string,int> z;
std::map<string,vector<string> > l;
int n;
int m;

int saisyo(string str){
	int ans=INF;
	if(z.count(str)!=0)ans=z[str];
	if(l.count(str)==0)return ans;
	int sum=0;
	for(int i=0;i<l[str].size();i++){
		sum+=saisyo(l[str][i]);
	}
	return min(ans,sum);
}

int main(void){
	while(cin>>n,n){
		z.clear();l.clear();
		string s;
		int v;
		for(int i=0;i<n;i++){
			cin>>s>>v;
			z[s]=v;
		}
		cin>>m;
		for(int i=0;i<m;i++){
			cin>>s>>v;
			string s2;
			for(int j=0;j<v;j++){
				cin>>s2;
				l[s].push_back(s2);
			}
		}
		cin>>s; //search
	cout<<saisyo(s)<<endl;
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
int n;
main()
{
	while(cin>>n,n)
	{
		map<string,int>M;
		map<string,vector<string> >A;
		map<string,int>cnt;
		for(int i=0;i<n;i++)
		{
			string s;int a;cin>>s>>a;M[s]=a;
			cnt[s]=0;
		}
		int m;cin>>m;
		for(int i=0;i<m;i++)
		{
			string s;cin>>s;
			int k;cin>>k;
			for(;k--;)
			{
				string t;cin>>t;
				A[s].push_back(t);
				cnt[s]++;
			}
		}
		vector<pair<int,string> >a;
		for(pair<string,int>it:M)
		{
			a.push_back(make_pair(it.second,it.first));
		}
		sort(a.begin(),a.end());
		for(int i=0;i<n;i++)
		{
			string s=a[i].second;
			if(cnt[s]==0)continue;
			int now=0;
			for(int j=0;j<cnt[s];j++)now+=M[A[s][j]];
			M[s]=min(M[s],now);
		}
		string s;cin>>s;
		cout<<M[s]<<endl;
	}
}