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 <map>
using namespace std;

struct Trn {
  int k;
  string *mat;
};

map<string, int> p;
map<string, Trn> q;

int min(string item) {
  int buy = p[item];
  if (q.find(item) != q.end()) {
    int trn = 0;
    for (int j=0; j<q[item].k; j++) {
      trn += min(q[item].mat[j]);
    }
    if (trn < buy) {
      return trn;
    }
  }
  return buy;
}

int main(void) {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) {
      break;
    }
    for (int j=0; j<n; j++) {
      string i;
      cin >> i;
      cin >> p[i];
    }
    int m;
    cin >> m;
    for (int j=0; j<m; j++) {
      string o;
      cin >> o;
      cin >> q[o].k;
      q[o].mat = new string[q[o].k];
      for (int l=0; l<q[o].k; l++) {
	cin >> q[o].mat[l];
      }
    }
    string item;
    cin >> item;
    cout << min(item) << endl;
    p.clear();
    if (!q.empty()) {
      for (map<string, Trn>::iterator j=q.begin(); j!=q.end(); j++) {
	delete[] j->second.mat;
      }
      q.clear();
    }
  }
  return 0;
}

C++: #include <iostream>
#include <fstream>
#include <algorithm>
#include <cassert>
#include <cctype>
#include <complex>
#include <cstdio>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;

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

int n,m;
map<string,int> t;
map<string,vector<string> > t2;

int f(string s){
	if(t2.find(s)==t2.end())return t[s];
	int c=0;
	rep(i,t2[s].size())c+=f(t2[s][i]);
	return min(t[s],c);
}

int main(){
	while(cin>>n&&n){
		t.clear();t2.clear();
		int p;
		string s,g;
		rep(i,n){
			cin>>s>>p;
			t[s]=p;
		}
		cin>>m;
		rep(i,m){
			cin>>s>>p;
			vector<string> v;
			rep(j,p){
				string st;
				cin>>st;
				v.push_back(st);
			}
			t2[s]=v;
		}
		cin>>g;
		cout<<f(g)<<endl;
	}
}

C++: #include<iostream>
#include<string>
#include<map>
using namespace std;main(){int n,c,m;for(;cin>>n,n;){
string s,t;map<string,int>M;
for(;n;n--)cin>>s>>c,M[s]=c;
for(cin>>n;n;M[s]=min(M[s],c),n--)for(c=0,cin>>s>>m;m;m--)cin>>t,c+=M[t];
cin>>s,cout<<M[s]<<endl;
}}

C++: #include<stdio.h>
#include<list>
#include<string.h>

class item{
 public:
  int pr;
  char name[101];
  std::list<int> ren;
};
item its[100];
int solve(int n){
  int sum;
  std::list<int>::iterator it;
  if(its[n].ren.empty()){
    return its[n].pr;
  }
  for(sum=0,it=its[n].ren.begin();it!=its[n].ren.end();it++){
    sum+=solve(*it);
  }
  return sum<its[n].pr?sum:its[n].pr;
}
int main(){
  int i,j,n,m,k,l,o;
  char buf[400];
  using namespace std;
  list<int>::iterator it;
  do{
    scanf("%d",&n);
    if(!n) break;
    for(i=0;i<n;i++) scanf("%s %d",its[i].name,&(its[i].pr));
    scanf("%d",&m);
    for(i=0;i<m;i++){
      scanf("%s ",buf);
      for(j=0;j<n;j++) if(!strcmp(buf,its[j].name)) break;
      scanf("%d ",&k);
      for(l=0;l<k-1;l++){
	scanf("%s ",buf);
	for(o=0;o<n;o++) if(!strcmp(its[o].name,buf)) break;
	its[j].ren.push_back(o);
      }
      scanf("%s",buf);
      for(o=0;o<n;o++) if(!strcmp(its[o].name,buf)) break;
      its[j].ren.push_back(o);
    }
    scanf("%s",buf);
    for(i=0;i<n;i++) if(!strcmp(buf,its[i].name)) break;
    printf("%d\n",solve(i));
  }while(1);
  return 0;
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<utility>
#include<vector>
#include<cmath>
#include<cstdio>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define it ::iterator
#define all(in) in.begin(),in.end()
const double PI=acos(-1);
const double ESP=1e-10;
using namespace std;
int main(){
  int n;
  while(cin>>n,n){
    map<string,int>in;
    rep(i,n){
      string s;
      int tmp;
      cin>>s>>tmp;
      in[s]=tmp;
    }
    int m;
    cin>>m;
    rep(i,m){
      string s;
      int k;
      cin>>s>>k;
      int co=0;
      rep(j,k){
	string tmp;
	cin>>tmp;
	co+=in[tmp];
      }
      if(in[s]>co)in[s]=co;
    }
    string out;
    cin>>out;
    cout<<in[out]<<endl;
  }

}

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

#define REP(i,n) for(int i = (int)(n) - 1; i >= 0; --i)

using namespace std;

int costs[101];
vector<int> recipe[101];
bool flags[101];

int getCost(int goal){
	if(recipe[goal].empty()) return costs[goal];
	flags[goal] = true;
	int sum = 0;
	REP(i, recipe[goal].size()){
		if(flags[recipe[goal][i]]){
			flags[goal] = false;
			return costs[goal];
		}
		sum += getCost(recipe[goal][i]);
	}
	flags[goal] = false;
	if(sum < costs[goal]){
		return sum;
	}else{
		return costs[goal];
	}
}

int main(){
	int n, m;
	while(true){
		cin >> n;
		if(n==0)break;
		
		REP(i, 101){
			flags[i] = false;
		}

		map<string,int> hash;
		
		REP(i,n){
			string name;
			cin >> name >> costs[i];
			hash.insert(map<string,int>::value_type(name,i));
			recipe[i].clear();
		}

		cin >> m;
		REP(i, m){
			string name;
			int item;
			int num;
			cin >> name >> num;
			item = hash[name];
			recipe[item].reserve(num);
			REP(j, num){
				string mate;
				int mat;
				cin >> mate;
				mat = hash[mate];
				recipe[item].push_back(mat);
			}
		}

		string goalName;
		int goal;
		cin >> goalName;
		goal = hash[goalName];

		cout << getCost(goal) << endl;
		
	}
	
	return 0;
}