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 <bits/stdc++.h>
using namespace std;

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int,int> pii;
//template<typename T> using vec=std::vector<T>;

const int inf=1<<30;
const long long int infll=1LL<<58;
const double EPS=1e-9;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
	os << "[";
	for (const auto &v : vec) {
		os << v << ",";
	}
	os << "]";
	return os;
}

map<string,int> table;
map<string,vector<string>> recipe;
map<string,int> opt;

int dfs(string& name,map<string,int>& state){
    state[name]=1;
    int res=table[name];
    if(recipe[name].empty()) return res;

    int tmp=0;
    for(auto &next:recipe[name]){
        if(state[next]==1) return res;
        if(state[next]==2) tmp+=opt[next];
        else tmp+=dfs(next,state);
    }
    res=min(res,tmp);

    state[name]=2;
    return opt[name]=res;
}

void solve(){
    int n;
    while(true){
        cin >> n;
        if(!n) break;

        table.clear();
        recipe.clear();
        opt.clear();

        rep(i,0,n){
            string name;
            int cost;
            cin >> name >> cost;
            table[name]=cost;
            opt[name]=inf;
        }

        int m;
        cin >> m;
        rep(i,0,m){
            string name1;
            int k;
            cin >> name1 >> k;
            rep(j,0,k){
                string name2;
                cin >> name2;
                recipe[name1].push_back(name2);
            }
        }

        string str;
        cin >> str;
        map<string,int> state;
        cout << dfs(str,state) << endl;
    }
}

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	solve();
	return 0;
}

C++: #include<cstdio>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<set>

using namespace std;

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

int item[111];
vector<int> cg[111];

int saiki(int a){
	if(cg[a].size()==0)return item[a];
	
	int sum=0;
	rep(i, cg[a].size()){
		sum+=saiki(cg[a][i]);
	}
	
	if(sum<item[a])return sum;
	return item[a];
}

int main(){
	while(1){
		int n;
		cin>>n;
		if(n==0)break;
		
		rep(i,111){
			item[i]=0;
			cg[i].clear();
		}
		map<string,int> N;
		
		rep(i,n){
			string a;int b;
			cin>>a>>b;
			
			N[a]=i;
			item[N[a]]=b;
		}
		
		int T;
		cin>>T;
		
		rep(i,T){
			string a;int b;
			cin>>a>>b;
			
			rep(j,b){
				string c;
				cin>>c;
				cg[N[a]].push_back(N[c]);
			}
		}
		
		string d;
		cin>>d;
		
		printf("%d\n",saiki(N[d]));
	}
}

C++: #include<iostream>
#include<map>
#include<string>
#include<vector>
using namespace std;
map<string,int>price;
map<string,vector<string> >rec;
int R(string o){
	int m=0,i;
	if(rec[o].size()){
		for(i=0;i<rec[o].size();i++)
			m+=R(rec[o][i]);
	}else
		m=price[o];
	if(price[o]&&price[o]<m)
		m=price[o];
	return m;
}
int main(){
	int n,m;
	string s,t;
	for(;cin>>n,n;){
		price.clear();
		rec.clear();
		for(;n--;){
			cin>>s;
			cin>>price[s];
		}
		cin>>n;
		for(;n--;){
			cin>>s>>m;
			for(;m--;){
				cin>>t;
				rec[s].push_back(t);
			}
		}
		cin>>s;
		cout<<R(s)<<endl;
	}
	return 0;
}

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