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<map>
#include<vector>
#include<string>
using namespace std;

map<string, vector<string> > mix;
map<string, int> prise;
map<string, int> min_prise;

int cal_min(string s)
{
  if(min_prise.find(s) != min_prise.end())
    return min_prise[s];
  if(mix.find(s) == mix.end())
    return prise[s];
  int p = 0;
  for(vector<string>::iterator i = mix[s].begin(); i != mix[s].end(); i++)
  {
    p += cal_min(*i);
    if(p >= prise[s])
    {
      min_prise.insert(pair<string, int>(s, prise[s]));
      return min_prise[s];
    }
  }
  min_prise.insert(pair<string, int>(s, p));
  return p;
}

int main()
{
  int n, m;
  while(1)
  {
    mix.clear();
    prise.clear();
    min_prise.clear();
    cin >> n;
    if(!n)
      break;
    for(int i = 0; i < n; i++)
    {
      string s;
      int p;
      cin >> s >> p;
      prise.insert(pair<string, int>(s, p));
    }
    cin >> m;

    for(int i = 0; i < m; i++)
    {
      string item;
      int d;
      vector<string> v;
      cin >> item >> d;
      for(int j = 0; j < d; j++)
      {
        string s;
        cin >> s;
        v.push_back(s);
      }
      mix.insert(pair<string, vector<string> >(item, v));
    }

    string str;
    cin >> str;
    cout << cal_min(str) << endl;
  }
}

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

using namespace std;

int main()
{
	int n,n2,n3;
	string name,lname;
	map<string,int> item;
	map<string,int> le;

	while( cin >> n && n )
	{
		for(int i=0;i<n;i++)
		{
			cin >> name;
			cin >> item[name];
		}
		cin >> n2;
		for(int i=0;i<n2;i++)
		{
			cin >> lname >> n3;
			for(int i=0;i<n3;i++)
			{
				cin >> name;
				if(le[name])
					le[lname]+=le[name];
				else 
					le[lname]+=item[name];
			}
		}
		cin >> lname;
		if(!le[lname])cout << item[lname] << endl;
		else cout << le[lname] << endl;
	}
}

C++: #include <bits/stdc++.h>
using namespace std;

struct material
{
    int price;
    vector<string> need;
};

int min_price(map<string, material>& mmap, string s)
{
    if (!mmap[s].need.empty()){
        int sum = 0;
        for (string name : mmap[s].need){
            sum += min_price(mmap, name);
        }
        mmap[s].price = min(mmap[s].price, sum);
        mmap[s].need.clear();
    }

    return mmap[s].price;
}

void solve(int n)
{
    int m;
    map<string, material> mmap;

    for (int i = 0; i < n; i++){
        string s;
        int p;

        cin >> s >> p;
        mmap[s] = { p, vector<string>() };
    }

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

        cin >> o >> k;
        while (k-- > 0){
            string q;

            cin >> q;
            mmap[o].need.push_back(q);
        }
    }
    for (auto i = mmap.begin(); i != mmap.end(); i++){
        i->second.price = min_price(mmap, i->first);
    }

    string s;
    cin >> s;
    printf("%d\n", mmap[s].price);
}

int main()
{
    int n;

    while (cin >> n, n){
        solve(n);
    }

    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

//define
#define int long long
#define UNIQUE(v) v.erase(unique(all(v)), v.end());
#define ZIP(v) sort(all(v)),UNIQUE(v)
#define ADD(a, b) a = (a + b) % mod
#define SUB(a, b) a = (a+mod-b)%mod
#define MUL(a, b) a = (a * b) % mod
#define repi(i,m,n) for(int i = m;i < n;i++)
#define drep(i,n,m) for(int i = n;i >= m;i--)
#define rep(i,n) repi(i,0,n)
#define rrep(i,n) repi(i,1,n+1)
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(), v.rend()
#define dmp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define fi first
#define se second
//template
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
  os << p.first << " " << p.second;return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
  for (auto it = v.begin();it != v.end();++it){
    if (it != v.begin())os << " ";os << *it;
  }return os;
}
template<typename T, int SIZE>
int array_length(const T (&)[SIZE]){return SIZE;}
template<typename T, int N>
void print(const T (&a)[N], int s = N, int t = -1, bool f = true){
	if(t == -1){rep(i,s){if(i)cout << " ";cout << a[i];}}
	else repi(i,s,t){if(i!=s)cout << " ";cout << a[i];}
	if(f)cout << "\n";
}
template<typename T, int N1, int N2>
void print(const T (&a)[N1][N2], int h = N1, int w = N2){
	rep(i,h){rep(j,w){cout << a[i][j] << " \n"[j==w-1];}}
}
//typedef
typedef pair<int,int> P;
typedef pair<int, P> PP;
typedef pair<P, int> Pi;
typedef vector<int> vi;
typedef deque<int> dq;
const int inf = 1e9+7;
const int INF = 1e18+7;


//DFS: 全ての点から深さ優先探索して、その帰りがけ順
class TopologicalSort{
public:
	int n;
	vector<int> ans, used;
	vector<vector<int> > G;
	void init(int N){
		n = N;
		used.resize(n);G.resize(n);
	}
	void add_edge(int from, int to){	//DAG
		G[from].pb(to);
	}
	void dfs(int v){
		if(used[v])return;
		used[v] = 1;
		for(int u: G[v])dfs(u);
		ans.pb(v);
	}
	bool sort(){
		rep(i,n)dfs(i);
		reverse(all(ans));
		return ans.size() == n;		//できなかった場合falseが返る
	}
};


int v[200];
vector<int> rec[200];
map<string, int> zip;
void init(){
	rep(i,200)v[i] = 0;
	rep(i,200)rec[i].resize(0);
	zip.clear();
}

signed main(){
	while(1){
		int n, m;
		cin >> n;
		if(n == 0)break;
		init();
		TopologicalSort T;T.init(n);
		rep(i,n){
			string str;int tmp;
			cin >> str >> tmp;
			zip[str] = i;v[i] = tmp;
		}
		cin >> m;
		rep(i,m){
			string str1, str2;int N;
			cin >> str1;cin >> N;
			rep(j,N){
				cin >> str2;
				T.add_edge(zip[str2], zip[str1]);
				rec[zip[str1]].pb(zip[str2]);
			}
		}
		
		T.sort();
		vector<int> order = T.ans;
		rep(i,n){
			int sum = 0, idx = order[i];
			if(rec[idx].size() == 0)continue;
			rep(j,rec[idx].size()){
				int r = rec[idx][j];
				sum += v[r];
			}
			chmin(v[idx], sum);
		}
		string t;cin >> t;
		cout << v[zip[t]] << endl;
		
	}
	return 0;
}