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>

struct data{
	char name[101];		//¼O
	int price;			//li
	int ren;			//BàÅ«é©
	int renkin[101];	//BàÅg¤itemÌzñÌY¦[0]ÉÍÂðüêÄ¨­
};
data item[101];
int visit[101];			//»ÌACeðêxKê½©Ç¤©B

int func(int number){
	int c=item[number].renkin[0];
	int ans=0;
	visit[number]=1;
//	printf("%s\n",item[number].name);
	if(item[number].renkin[0]==0){
		return item[number].price;
	}
	for(int i=1;i<=c;i++){
		if(visit[item[number].renkin[i]]==1){
		//	printf("visited!! %s %d\n",item[item[number].renkin[i]].name,item[item[number].renkin[i]].price);
			ans+=item[item[number].renkin[i]].price;
		}
		else if(item[item[number].renkin[i]].ren==0){
//			printf("Can't!!   %s %d\n",item[item[number].renkin[i]].name,item[item[number].renkin[i]].price);
			ans+=item[item[number].renkin[i]].price;
		}
		else {
//			printf("renkin!!  %s %d\n",item[item[number].renkin[i]].name,item[item[number].renkin[i]].price);
			ans+=func(item[number].renkin[i]);
		}
	}
	if(ans>item[number].price)return item[number].price;
	else {
		item[number].price=ans;
		return ans;
	}
}
			

int main(void){
	int n,i,j,l;
	while(scanf("%d",&n),n){
		
		int m,k,t;
		char temp[101];
		for(i=0;i<n;i++){
			scanf("%s %d",item[i].name,&item[i].price);
		}
		//±±©çBà
		scanf("%d",&m);
		for(i=0;i<m;i++){
			
			//Å«éàÌ
			scanf("%s",temp);
			for(j=0;j<n;j++){
				if(!(strcmp(item[j].name,temp))){
					item[j].ren=1;
					break;
				}
			}
			t=j;
			puts(item[t].name);
			//´¿
			scanf("%d",&k);
			item[t].renkin[0]=k;
			for(j=0;j<k;j++){
				scanf("%s",temp);
				for(l=0;l<n;l++){
					if(!(strcmp(item[l].name,temp))){
						item[t].renkin[j+1]=l;
						break;
					}
				}
			}
		}
		scanf("%s",temp);
		for(i=0;i<n;i++){
			if(!(strcmp(item[i].name,temp))){
				break;
			}
		}
		//±±ÜÅÇÝÝ
		
		
		//wè³ê½ACeÅÄAµÄ¢­
		//©ªªoÄ«½ç¤BBàÅ«È¢B»±ðKê½©Å»fH
	//	puts("ÄA");
		printf("%d\n",func(i));
		
		for(i=0;i<101;i++){
			visit[i]=0;
			item[i].ren=0;
			item[i].price=0;
		}
	}
}

C++: #include <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second

template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, pll> pip;
const ll INF = 1ll<<57;
const ll MOD = 1000000007;
const double EPS  = 1e-9;

int N, M;
ll cost[200];
string S[100], O[100], Q[100][100], T;
int P[100], K[100];
vector<int> g[100];

int main() {
	while (cin >> N, N) {
		REP(i, N) cin >> S[i] >> P[i];
		cin >> M;
		REP(i, M) {
			cin >> O[i] >> K[i];
			REP(j, K[i]) cin >> Q[i][j];
		}
		cin >> T;
		
		map<string, int> conv;
		REP(i, N) if (conv.find(S[i]) == conv.end()) conv[S[i]] = (int)conv.size() - 1;
		REP(i, M) {
			if (conv.find(O[i]) == conv.end()) conv[O[i]] = (int)conv.size() - 1;
			REP(j, K[i]) if (conv.find(Q[i][j]) == conv.end()) conv[Q[i][j]] = (int)conv.size() - 1;
		}
		
		REP(i, M) {
			g[i].push_back(conv[O[i]]);
			REP(j, K[i]) g[i].push_back(conv[Q[i][j]]);
		}
		
		fill(cost, cost + 200, INF);
		REP(i, N) chmin(cost[conv[S[i]]], P[i]);
		
		while (true) {
			bool update = false;
			REP(i, M) {
				ll sum = 0;
				FOR(j, 1, g[i].size()) sum += cost[g[i][j]];
				update |= chmin(cost[g[i][0]], sum);
			}
			if (!update) break;
		}
		
		cout << cost[conv[T]] << endl;
	}
	return 0;
}

C++: #include <unordered_map>
#include <string>
#include <vector>
#include <iostream>

class Item {
public:
	Item(const std::string &n, const int &p) :name(n), price(p), made_from() {};
	Item() :name(), price(), made_from() {};
	void add_recipe(Item* item) {
		made_from.push_back(item);
	}
	int get_price() {
		if (made_from.size() == 0) {
			return price;
		}
		else {
			int temp = 0;
			for (auto i : made_from) {
				temp += i->get_price();
			}
			return (price > temp) ? temp : price;
		}
	}
private:
	std::string name;
	int price;
	std::vector<Item*> made_from;
};
int main() {
	int n = 1;
	std::cin >> n;
	while (n != 0) {
		std::unordered_map<std::string, Item> map;
		for (auto i = 0; i < n; ++i) {
			std::string name;
			int price;
			std::cin >> name >> price;
			map[name] = Item(name, price);
		}
		std::cin >> n;
		for (auto i = 0; i < n; ++i) {
			std::string item;
			std::cin >> item;
			int m;
			std::cin >> m;
			for (auto j = 0; j < m; ++j) {
				std::string factor;
				std::cin >> factor;
				map[item].add_recipe(&map[factor]);
			}
		}
		std::string order;
		std::cin >> order;
		std::cout << map[order].get_price() << std::endl;
		std::cin >> n;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<n;i++)
using namespace std;

int main() {
	int n;
	while (cin >> n, n) {
		map<string, int>cost;
		map<string, vector<string>>c;
		rep(i, n) {
			string s; int d; cin >> s >> d;
			cost[s] = d;
		}
		int m; cin >> m;
		rep(i, m) {
			string s; int d; cin >> s >> d;
			rep(j, d) {
				string S; cin >> S;
				c[s].push_back(S);
			}
		}
		rep(i, n) {
			for (auto&p : cost) {
				if (!c[p.first].empty()) {
					int cnt = 0;
					for (auto j : c[p.first])cnt += cost[j];
					p.second = min(p.second, cnt);
				}
			}
		}
		string s; cin >> s;
		cout << cost[s] << endl;
	}
}

C++: #include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
typedef map<string,int> msi;
const int INF=2<<25;
msi p;
int n,m,price[100];
vector<vector<int> > recipe[100];
int search(int x,bool used[100]){
	int minim=price[x];
	if(used[x])
	return INF;
	else
	used[x]=true;
	for(int i=0;i<recipe[x].size();i++){
		int sum=0;
		for(int j=0;j<recipe[x][i].size();j++)
			sum+=search(recipe[x][i][j],used);
		minim=min(minim,sum);
	}
	used[x]=false;
	return minim;
		
}
int main() {
	string s,sb;
	while(cin >> n && n!=0){
		for(int i=0;i<n;i++){
			cin >> s >> price[i];
			p.insert(msi::value_type(s,i));
		}
		cin >> m;
		int num;
		for(int i=0;i<m;i++){
			vector<int> material;
			cin >> s >> num;
			for(int j=0;j<num;j++){
			cin >> sb; 
			material.push_back(p[sb]);
			}
			recipe[p[s]].push_back(material);
		}
		cin >> s;
		bool used[100]={};
		cout << search(p[s],used) << endl;
		for(int i=0;i<100;i++){
			recipe[i].clear();
			price[i]=0;
		}
		p.clear();
	}
	// your code goes here
	return 0;
}