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 <queue>
#include <map>
#include <algorithm>
using namespace std;

typedef pair<int, int> P;
typedef map<string, P> IM;
const int NMAX = 100;
int N, M;
int depends[NMAX][NMAX];
int origCosts[NMAX];
int target;
int counts[NMAX];
int costs[NMAX];
string names[NMAX];

bool input() {
  IM items;

  cin >> N;
  if (!N) {
    return false;
  }
  for (int i = 0; i < N; ++i) {
    string name;
    int cost;
    cin >> name;
    cin >> cost;
    items.insert(IM::value_type(name, P(i, cost)));
    names[i] = name;
    origCosts[i] = cost;
  }
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      depends[i][j] = 0;
    }
  }
  cin >> M;
  for (int i = 0; i < M; ++i) {
    string s1;
    int num;
    cin >> s1 >> num;
    int a = items[s1].first;
    for (int j = 0; j < num; ++j) {
      string s2;
      cin >> s2;
      int b = items[s2].first;
      ++depends[a][b];
    }
  }

  string st;
  cin >> st;
  target = items[st].first;
  return true;
}

int solve() {
  for (int i = 0; i < N; ++i) {
    counts[i] = 0;
  }
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      if (depends[i][j]) {
        ++counts[i];
      }
    }
  }

  queue<int> q;
  while (1) {
    for (int i = 0; i < N; ++i) {
      if (!counts[i]) {
        q.push(i);
      }
    }
    if (q.empty()) {
      break;
    }
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      int y = 0;
      bool assembled = false;
      for (int i = 0; i < N; ++i) {
        if (depends[x][i]) {
          y += depends[x][i] * costs[i];
          assembled = true;
        }
      }
      if (!assembled) {
        costs[x] = origCosts[x];
      } else {
        costs[x] = min(origCosts[x], y);
      }
      --counts[x];
      for (int i = 0; i < N; ++i) {
        if (depends[i][x]) {
          --counts[i];
        }
      }
    }
  }

  return costs[target];
}

int main() {
  while (input()) {
    cout << solve() << endl;
  }
}

C++: /*
 * src.cpp
 *
 *  Created on: 2016/07/29
 *      Author: joi
 */

#include <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,a) FOR(i,0,a)

const int INF=1e8;

int n,m;
map<string,int> item;
map<string,vector<string> > w;

map<string,bool> flg;

int dfs(string s){
	if (flg[s]){
		return item[s];
	}
	int res=0;
	vector<string> v=w[s];
	flg[s]=true;
	if (v.size()==0){
		res=INF;
	}else{
		REP(i,(int)v.size()){
			res+=dfs(v[i]);
		}
	}
	return item[s]=min(item[s],res);
}

int main(){
	do{
		cin>>n;
		if (n){
			item.clear();
			w.clear();
			flg.clear();
			REP(i,n){
				string s;
				int p;
				cin.ignore();
				cin>>s>>p;
				item[s]=p;
			}
			cin>>m;
			cin.ignore();
			REP(i,m){
				string s;
				cin>>s;
				int k;
				cin>>k;
				REP(j,k){
					string q;
					cin>>q;
					w[s].push_back(q);
				}
			}
			string s;
			cin>>s;
			cout<<dfs(s)<<endl;
		}
	}while(n);
	return 0;
}

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

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

using namespace std;

typedef long long ll;

vector<string> split(string &str,char delim)
{
	vector<string> res;
	size_t current = 0,found;
	while((found = str.find_first_of(delim,current)) != string::npos)
	{
		res.push_back(string(str,current,found  - current));
		current = found + 1;
	}
	res.push_back(string(str,current,str.size() - current));
	return res;
}
int main()
{
	int n,m;
	while(cin >> n && n)
	{
		map<string,ll> ma;
		
		rep(i,n)
		{
			string s;
			ll temp;
			cin >> s >> temp;
			ma[s] = temp;
		}

		cin >> m;
		vector<vector<string> > v(m);
		
		rep(i,m)
		{
			string s1;
			ll t;
			cin >> s1 >> t;
			
			v[i].push_back(s1);

			rep(j,t)
			{
				cin >> s1;
				v[i].push_back(s1);
			}
		}
		
		rep(i,m)
		{
			rep(j,m)
			{
				ll t = 0;
				REP(k,1,v[j].size())
				{
					t += ma[v[j][k]];
				}
				ma[v[j][0]] = min(ma[v[j][0]],t);
			}
		}
		
		string ans;
		cin >> ans;

		cout << ma[ans] << endl;
	}
	return 0;
}

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

#define INF (10000000)
#define MIN(x, y) ((x) < (y) ? (x) : (y))

using namespace std;

map<string, int> ItemList;
map<string, list<string> > WroughtList;

int GetMinCost(string& butt)
{
	int wrought_cost;
	map<string, list<string> >::iterator it;
	map<string, int>::iterator mit;
	
	it = WroughtList.find(butt);
	
	if (it != WroughtList.end()){
		wrought_cost = 0;
		for (list<string>::iterator lit = it->second.begin(); lit != it->second.end(); lit++){
			wrought_cost += GetMinCost(*lit);
		}
	}
	else {
		wrought_cost = INF;
	}
	
	mit = ItemList.find(butt);
	
	return (MIN(wrought_cost, mit->second));
}

int main(void)
{
	int ItemCnt;
	int WroughtCnt;
	string sarch_item;
	pair<string, int> add;
	pair<string, list<string> > wadd;
	
	while (1){
		ItemList.clear();
		WroughtList.clear();
		cin >> ItemCnt;
		if (ItemCnt == 0) break;
		for (int i = 0; i < ItemCnt; i++){
			cin >> add.first >> add.second;
			ItemList.insert(add);
		}
		cin >> WroughtCnt;
		for (int i = 0; i < WroughtCnt; i++){
			int cnt;
			
			cin >> wadd.first >> cnt;
			wadd.second.clear();
			for (int i = 0; i < cnt; i++){
				string name;
				
				cin >> name;
				wadd.second.push_back(name);
			}
			WroughtList.insert(wadd);
		}
		
		cin >> sarch_item;
		
		cout << GetMinCost(sarch_item) << 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 < 10 ; 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;
}