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 <stdio.h>
#include <string.h>

int n;

struct item{
    char name[256];
    int cost;
    char used[100][256];
    int size;
} ;

item list[100];

int getCost(int vertex)
{
    int i, j;
    int ans;
    
    if (list[vertex].size == 0){
        return (list[vertex].cost);
    }
    else {
        ans = 0;
        for (i = 0; i < list[vertex].size; i++){
            for (j = 0; j < n; j++){
                if (strcmp(list[vertex].used[i], list[j].name) == 0){
                    ans += getCost(j);
                }
            }
        }
        list[vertex].cost = list[vertex].cost > ans ? ans : list[vertex].cost;
    }
    return (list[vertex].cost);
}

int main(void)
{
    int i, j, k;
    int m, kk;
    char key[256], temp[256];
    int look, sum;
    
    while (1){
        scanf("%d", &n);
        
        if (n == 0){
            break;
        }
        
        for (i = 0; i < n; i++){
            scanf("%s%d", list[i].name, &list[i].cost);
            list[i].size = 0;
        }
        
        scanf("%d", &m);
        for (i = 0; i < m; i++){
            scanf("%s", key);
            for (j = 0; j < n; j++){
                if (strcmp(key, list[j].name) == 0){
                    look = j;
                }
            }
            scanf("%d", &kk);
            list[look].size = kk;
            for (j = 0; j < kk; j++){
                scanf("%s", temp);
                for (k = 0; k < n; k++){
                    if (strcmp(temp, list[k].name) == 0){
                        strcpy(list[look].used[j], temp);
                    }
                }
            }
        }
        scanf("%s", key);
        for (j = 0; j < n; j++){
            if (strcmp(key, list[j].name) == 0){
                look = j;
            }
        }
        
        printf("%d\n", getCost(look));
        
    }
    
    return (0);
}

C++: #include <cstdio>
#include <cctype>
#include <utility>
#include <vector>
#include <unordered_map>
#include <string>
#include <functional>
#include <numeric>
using namespace std;

#define _gp(l) const auto gcu{getchar##l}; const auto pcu{putchar##l}
#ifdef __linux
_gp(_unlocked);
#else
_gp();
#endif
#define _DEF(r, n, ...) inline r n(__VA_ARGS__) noexcept
#define _T template<typename T>
#define _HT template<typename H,typename... T>
_T _DEF(T,in,int c){T n{};int m{1};while(isspace(c)){c=gcu();}if(c=='-')m=-1,c=gcu();do{n=10*n+(c-'0'),c=gcu();}while(c>='0'&&c<='9');return m*n;}
_DEF(int,in,){return in<int>(gcu());}
#define _SCAN(...) _DEF(bool,scan,__VA_ARGS__)
_T _SCAN(T &n){int c{gcu()};return c==EOF?false:(n=in<T>(c),true);}
_DEF(bool, scan, int &c){c=gcu();gcu();return c!=EOF;}
#define _OUT(...) _DEF(void,out,__VA_ARGS__)
#define _OUTL(...) _DEF(void,outl,__VA_ARGS__)
_OUT(bool b){pcu('0'+b);}
_OUT(const char *s){while(*s)pcu(*s++);}
_OUT(char c){pcu(c);}
#ifdef _GLIBCXX_STRING
_SCAN(string &s){int c;s="";for(;;){c=gcu();if(c=='\n'||c==' ')return true;else if(c==EOF)return false;s+=(char)c;}}
_OUT(string s){for(char c:s)pcu(c);}
#endif
_T _OUT(T n){static char b[20];char *p{b};T m=n<0?pcu('-'),-1:1;if(!n)*p++='0';else while(n)*p++=(char)(n%10*m+'0'),n/=10;while(p!=b)pcu(*--p);}
_OUTL(){out('\n');}
#ifdef _GLIBCXX_VECTOR
_T _OUT(vector<T> v){for(T &x:v)out(&x == &v[0]?"":" "),out(x);}
#endif
_HT _SCAN(H &h,T&&... t){return scan(h)&&scan(t...);}
_HT _OUT(H&& h, T&&... t){out(h);out(move(t)...);}
template <typename... T> _OUTL(T&&... t){out(move(t)...);outl();}
struct range{int e,b{0},s{1};range(int _b,int _e,int _s):e(_e),b(_b),s(_s){}range(int _b,int _e):e(_e),b(_b){}range(int _e):e(_e){}
	struct it{int v,s;it(int _v,int _s):v(_v),s(_s){}operator int()const{return v;}operator int&(){return v;}int operator*()const{return v;}it& operator++(){v+=s;return *this;}};
	it begin(){return{b, s};}it end(){return{e,s};}};

struct item {
	int p;
	vector<int> c;
};

int main() {
	string s;
	for (int n; (n = in());) {
		unordered_map<string, int> t;
		vector<item> r(n);
		for (int i: range(n)) {
			scan(s);
			t[s] = i;
			r[i].p = in();
		}
		for (int m {in()}; m; m--) {
			scan(s);
			auto &o {r[t[s]].c};
			for (int i {in()}; i; i--) {
				scan(s);
				o.push_back(t[s]);
			}
		}
		function<int(int)> mc{[&](int i) {
			item &o {r[i]};
			return o.c.size() ?
				min(o.p, accumulate(begin(o.c), end(o.c), 0,
									[&](int a, int j){return a + mc(j);})) :
				o.p;
		}};
		scan(s);
		outl(mc(t[s]));
	}
}

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);
    if(its[n].pr<sum) return its[n].pr;
  }
  return sum;
}
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));
    for(i=0;i<n;i++) its[i].ren.clear();
  }while(1);
  return 0;
}

C++: #include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;
int n, m;
map<string, int> items;
map<string, vector<string> > alc;

map<string, int> memo;
int minPrice(const string& t) {
	vector<string>& mats = alc[t];
	if (!mats.size()) return items[t];
	map<string, int>::iterator it = memo.find(t);
	if (it != memo.end()) return it->second;
	int ap = 0;
	for (unsigned i = 0; i < mats.size(); i++) {
		ap += minPrice(mats[i]);
	}
	return memo[t] = min(items[t], ap);
}

int main () {
	while (cin >> n, n) {
		for (int i = 0; i < n; i++) {
			string name;
			int value;
			cin >> name >> value;
			items[name] = value;
		}
		cin >> m;
		for (int i = 0; i < m; i++) {
			string name;
			int k;
			cin >> name >> k;
			vector<string> mats;
			for (int j = 0; j < k; j++) {
				string mat;
				cin >> mat;
				mats.push_back(mat);
			}
			alc[name] = mats;
		}
		string target;
		cin >> target;
		cout << minPrice(target) << endl;
	}
	return 0;
}