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 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[100];
string S[100], O[100], Q[100][100], T;
ll 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) conv[S[i]] = 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 + 100, 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<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<map>
#include<queue>
using namespace std;
typedef pair<string,int> P;
map<string,vector<string> > rm;
map<string,int> I;
int N,M;
map<string,int> dp;
int solve(string S){
  if(dp[S]!=0) return dp[S]; 
  if(rm[S].empty()) return I[S];
  int n = rm[S].size();
  int ret=0;
  for(int i=0;i<n;i++){
    ret+=solve(rm[S][i]);
  }
  ret = min(I[S],ret);
  return dp[S]=ret;
}

main(){
  while(1){
    cin >> N;
    if(!N) break;
    for(int i=0;i<N;i++){
      string Is;
      int Ii;
      cin >> Is >> Ii;
      I[Is]=Ii;
    }
    cin >> M;
    for(int i=0;i<M;i++){
      string s;
      int k;
      cin >> s >> k;
      for(int i=0;i<k;i++){
	string si;
	cin >> si;
	rm[s].push_back(si);
      }
    }
    string Q;
    cin >> Q;
    cout << solve(Q) << endl;
    rm.clear();
    I.clear();
  }
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<map>
using namespace std;
int main() {
	vector<long>ll;
	int n, ex;
	string s;
	while (cin >> n){
		if (n == 0)break;
		map<string, long>l;
		for (int i = 0; i < n; i++){
			cin >> s >> ex;
			l[s] = ex;
		}
		cin >> n;
		for (int i = 0; i < n; i++){
			cin >> s >> ex;
			long sum = 0;
			for (int i = 0; i < ex; i++) {
				string str;
				cin >> str;
				sum += l[str];
			}
			l[s] = min(l[s], sum);
		}
		cin >> s;
		ll.push_back(l[s]);
	}
	for (int i : ll) {
		cout << i << endl;
	}
	char c;
	cin >> c;
	return 0;
}

C++: #include <cstdio>
#include <vector>
#include <map>
#include <string>

using namespace std;

map<string,int> item;

const int INF = 2000000000;


class Recipe{
public:
	string To;
	vector<string> From;
	int GetCost();
};

map<string,Recipe> recipe;

int Recipe::GetCost(){
	if(From.size() == 0){
		return INF;
	}
	int c = 0;
	vector<string>::iterator it;
	for(it = From.begin();it<From.end();it++){
		c += item[*it] < recipe[*it].GetCost() ? item[*it] :recipe[*it].GetCost() ;
	}
	return c;
}


int itemn;
int recipen;

int main(){
	int self;
	char str[256];
	while(scanf("%d",&itemn) != EOF){
		//if(itemn == 0){break;}
		//printf("CASE\n");
		item.clear();
		recipe.clear();
		//printf("ITEMS %d:\n",itemn);
		for(int i=0;i<itemn;i++){
			scanf("%s %d",str,&self);
			item[str] = self;
			//printf("%s	%d\n",str,self);
		}
		if(scanf("%d",&recipen) == EOF) break;
	
		for(int i=0;i<recipen;i++){
			Recipe r;
			scanf("%s %d",str,&self);
			r.To = str;
			for(int j=0;j<self;j++){
				scanf("%s",str);
				r.From.push_back(str);
			}
			recipe[r.To] = r;
		}
		scanf("%s",str);
		
		//printf("TARGET:%s\n",str);
		printf("%d\n" , item[str] < recipe[str].GetCost() ? item[str] : recipe[str].GetCost() );
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <utility>
#include <queue>
#define rep2(x,from,to) for(int x=(from);(x)<(to);(x)++)
#define rep(x,to) rep2(x,0,to)
using namespace std;
string item[110];
int cost[110][110];
int solve(int x, int n) {
	int ans = 0;
	bool f = 1;
	rep(i,n) {
		if(i==x) continue;
		if(cost[x][i]!=-1) {
			f=0;
			ans += solve(i,n);
		}
	}
	if(f) return cost[x][x];
	return min(cost[x][x], ans);

}
int main(){
	int n, k, m;
	string s;
	while(cin >> n, n) {
		rep(i,110) {
			rep(j,110) {
				cost[i][j] = -1;
			}
		}
		rep(i,n) {
			cin >> item[i] >> cost[i][i];
		}
		cin >> k;
		rep(i,k) {
			cin >> s >> m;
			rep(j,100) {
				if(item[j] == s) {
					rep(p,m) {
						cin >> s;
						rep(q,100) {
							if(item[q] == s) {
								cost[j][q] = cost[q][q];
								break;
							}
							
						}
					}
					break;
				}
			}
		}
		cin >> s;
		rep(i,100) {
			if(item[i] == s) {
				cout << solve(i,n) << endl;
				break;
			}
		}
	}
}

C++: #include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<string>

using namespace std;

vector<int> list[100];
int item[100];

int saiki(int n){
	if(list[n].empty()==1){
		return item[n];
	}
	
	int cont=0;
	for(int i=0;i<list[n].size();i++){
		cont+=saiki(list[n][i]);
	}
	
	return min(cont,item[n]);
}

int main(){
	map<string,int> name;
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		string a;int b;
		cin>>a>>b;
		name[a]=i;
		item[i]=b;
	}
	for(int i=0;i<100;i++){
		list[i].clear();
	}
	
	int m;
	cin>>m;
	for(int i=0;i<m;i++){
		string a;int b;
		cin>>a>>b;
		for(int j=0;j<b;j++){
			string c;
			cin>>c;
			list[name[a]].push_back(name[c]);
		}
	}
	
	string a;
	cin>>a;
	printf("%d\n",saiki(name[a]));
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
int main(){

	map<string, int> end;
	int m;
	int cost; string material;
	while (cin >> m, m){
		for (; m > 0; m--){
			cin >> material >> cost;
			end.insert(map<string, int>::value_type(material, cost));
		}
		cin >> m;
		for (; m > 0; m--){
			string sozai; int kaisuu; int sum = 0;
			cin >> sozai >> kaisuu;
			for (; kaisuu > 0; kaisuu--){
				cin >> material;
				if (end.find(material) != end.end()) sum += end[material];
			}
			if (sum < end[sozai]) end[sozai] = sum;
			sum = 0;
		}
		string in;
		cin >> in;
		cout << end[in] << endl;
	}
	return 0;
}