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 <iomanip>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <utility>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
 
using namespace std;
 
#define rep(i,n) for(int i=0; i<(n); i++)
#define repc(i,s,e) for(int i=(s); i<(e); i++)
#define pb(n) push_back((n))
#define mp(n,m) make_pair((n),(m))
#define all(r) r.begin(),r.end()
#define fi first
#define se second
 
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vl;
typedef vector<vl> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

typedef pair<int, pii> pip;
 
 
 
const int INF = 1000000;
const double EPS = 1e-8;
const int mod = 1e9 + 7;
 



int main(){
	int n, m, a, sum;
	string s, t;
	while(cin>> n && n > 0){
		//cin>>m;
		m = n;
		map<string,int> mp;
		for(int i= 0; i < m; i++){
			cin>>s>>a;
			mp[s] = a;
		}
		//cout<<n<<endl;
		cin>>m;
		for(int i = 0; i < m; i++){
			cin>>s>>a;
			sum = 0;
			for(int j = 0; j < a; j++){
				cin>>t;
				sum += mp[t];
			}
			mp[s] = min(mp[s], sum);
		}
		cin>>s;
		cout<<mp[s]<<endl;
	}
}

C++: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define EQ(a,b) (abs((a)-(b))<EPS)
int n,m;
struct item
{
	string name;
	int cost,size;
	vector<string> le;
};
item lis[100];
int mysearch(string s)
{
	for(int i=0;i<n;i++)
	{
		if(lis[i].name==s)return i;
	}
}
int getcost(int v)
{
		if(lis[v].size==0)return lis[v].cost;
		else
		{
			int ans=0;
			for(int i=0;i<lis[v].size;i++)
			{
				ans+=getcost(mysearch(lis[v].le[i]));
			}
			lis[v].cost=min(lis[v].cost,ans);
			return lis[v].cost;
		}
	
}
int main()
{
	while(1)
	{
		cin >> n;
		if(n==0)break;
		string s;
		int c;
		for(int i=0;i<n;i++)
		{
			cin >> s >> c;
			lis[i].name=s;
			lis[i].cost=c;
			lis[i].size=0;
		}
		cin >> m;
		for(int i=0;i<m;i++)
		{
			int t,k;
			cin >> s;
			cin >> t;
			for(int j=0;j<t;j++)
			{
				string st;
				cin >> st;
				k=mysearch(s);
				lis[k].le.pb(st);
			}
			lis[k].size=t;
		}
		string str;
		cin >> str;
		cout << getcost(mysearch(str))<< endl;
	}
	return 0;
}

C++: #include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <functional>
#include <utility>
#include <algorithm>
#include <numeric>
#include <typeinfo>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <ctime>

using namespace std;

#define dump(n) cout<<"# "<<#n<<"="<<(n)<<endl
#define debug(n) cout<<__FILE__<<","<<__LINE__<<": #"<<#n<<"="<<(n)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define iter(c) __typeof((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();i++)
#define allof(c) (c).begin(),(c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int,int> pii;

int solve(string& name,map<string,int>& prices,map<string,vs>& needs)
{
	if(needs.count(name)==0)
		return prices[name];
	int res=0;
	foreach(i,needs[name])
		res+=solve(*i,prices,needs);
	return res;
}

int main()
{
	for(int n;cin>>n,n;){
		map<string,int> prices;
		rep(i,n){
			string name;
			int price;
			cin>>name>>price;
			prices[name]=price;
		}
		map<string,vs> needs;
		int m;
		cin>>m;
		rep(i,m){
			string name;
			int k;
			cin>>name>>k;
			rep(j,k){
				string elem;
				cin>>elem;
				needs[name].push_back(elem);
			}
		}
		
		string name;
		cin>>name;
		cout<<solve(name,prices,needs)<<endl;
	}
	
	return 0;
}

C++: #include<iostream>
#include<string>
#include<map>
#include<vector>
#include<cassert>
using namespace std;

#define MAX 200

class Item{
    public:
    string name;
    int cost;
    vector<vector<string> > recipes;

    Item(){}
    Item( string name, int cost ): name(name), cost(cost){ recipes.clear(); }

    void addRecipe(vector<string> r ){ recipes.push_back(r);}
};

int n;
map<string, int> N_I;
Item items[MAX];

int getCost( string name ){
    Item item = items[ N_I[name] ];
    int cost = item.cost;

    for ( int i = 0; i < item.recipes.size(); i++ ){
	vector<string> recipe = item.recipes[i];
	int sum = 0;
	for ( int j = 0; j < recipe.size(); j++ ){
	    sum += getCost( recipe[j] );
	}
	cost = min( cost, sum );
    }

    return cost;
}

main(){
    int q, cost, nr, k;
    string name, source;
    while( cin >> n && n){
	for ( int i = 0; i < n; i++ ){
	    cin >> name >> cost;
	    assert( name.size() <= 100 );
	    items[i] = Item(name, cost);
	    N_I[name] = i;
	}
	cin >> nr;
	for ( int i = 0; i < nr; i++ ){
	    cin >> name >> k;
	    vector<string> recipe;
	    for ( int j = 0; j < k; j++ ){
		cin >> source;
		recipe.push_back(source);
	    }
	    items[ N_I[name] ].addRecipe(recipe);
	}
	cin >> name;
	cout << getCost( name ) << endl;
    }
}

C++: #include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int main()
{
	while (true) {
		int n;
		cin >> n;
		if (n == 0) break;
		map<string, int> name;
		vector<int> price;
		string t;
		int a;
		for (int i=0; i<n; ++i) {
			cin >> t >> a;
			name[t] = i;
			price.push_back(a);
		}

		int m;
		cin >> m;
		vector<vector<int> > renkin(n);
		for (int i=0; i<m; ++i) {
			vector<int> t;
			string s;
			int a;
			cin >> s >> a;
			for (int j=0; j<a; ++j) {
				string u;
				cin >> u;
				t.push_back(name[u]);
			}

			renkin[name[s]] = t;
		}

		string target;
		cin >> target;

		bool changed = true;
		while (changed) {
			changed = false;
			for (int i=0; i<renkin.size(); ++i) {
				if (renkin[i].empty()) continue;
				int c = 0;
				for (int j=0; j<renkin[i].size(); ++j)
					c += price[renkin[i][j]];
				if (price[i] > c) {
					changed = true;
					price[i] = c;
				}
			}
		}

		cout << price[name[target]] << endl;
	}
	return 0;
}