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<algorithm>
#include<cassert>
#include<map>
#include<vector>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define N 100

const int INF = 1000100; 
int table[N];
int buycost[N];

int solve(int now,vector<int> *make){
  //  if ( table[now] != -1)return table[now];
  if(  make[now].size()==0)return table[now]=buycost[now];
  

  int ret = buycost[now],tmp=0;  
  rep(i,make[now].size()){
    tmp+=solve(make[now][i],make);
  }
  
  ret= min(ret,tmp);
  return table[now]=ret; 
}

main(){
  int n;
  while(cin>>n && n){
    map<string,int> M;
    rep(i,n){
      string t;int a;
      cin>>t>>a;
      M[t]=i;
      buycost[i]=a;
      table[i]=-1;
    }
    
    vector<int> make[n];
    cin>>n;
    rep(i,n){
      string a;
      cin>>a;
      int now =M[a],m;
      cin>>m;
      rep(j,m){
	cin>>a;
	make[now].push_back(M[a]);
      }     
    }
    string tmp;
    cin>>tmp;
    int tar=M[tmp];
    cout << solve(tar,make) << endl;
    
  }
  return false;
}

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]<m)
		m=price[o];
	return m;
}
int main(){
	int n,m;
	string s,t;
	for(;cin>>n,n;){
		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 <stdio.h>
#include <string.h>

struct d{
	char M[101];
	int p;
	int r;
	int rk[101];
};
d t[101];
int v[101];

int func(int n){
	int c=t[n].rk[0];
	int a=0;
	v[n]=1;
	if(t[n].rk[0]==0){
		return t[n].p;
	}
	for(int i=1;i<=c;i++){
		if(v[t[n].rk[i]]==1){
			a+=t[t[n].rk[i]].p;
		}
		else if(t[t[n].rk[i]].r==0){
			a+=t[t[n].rk[i]].p;
		}
		else {
			a+=func(t[n].rk[i]);
		}
	}
	if(a<t[n].p)
		t[n].p=a;
	
	return t[n].p;
}
			

int main(void){
	int n,i,j,l;
	while(scanf("%d",&n),n){
		
		int m,k,V;
		char T[101];
		for(i=0;i<n;i++){
			scanf("%s %d",t[i].M,&t[i].p);
		}
		scanf("%d",&m);
		for(i=0;i<m;i++){
			
			scanf("%s",T);
			for(j=0;j<n;j++){
				if(!(strcmp(t[j].M,T))){
					t[j].r=1;
					break;
				}
			}
			V=j;
			scanf("%d",&k);
			t[V].rk[0]=k;
			for(j=0;j<k;j++){
				scanf("%s",T);
				for(l=0;l<n;l++){
					if(!(strcmp(t[l].M,T))){
						t[V].rk[j+1]=l;
						break;
					}
				}
			}
		}
		scanf("%s",T);
		for(i=0;i<n;i++){
			if(!(strcmp(t[i].M,T))){
				break;
			}
		}
		printf("%d\n",func(i));
		
		for(i=0;i<101;i++){
			v[i]=0;
			t[i].r=0;
			t[i].p=0;
		}
	}
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <map>
#define INF (2 << 28)
using namespace std;

map<string, int> item;
map<string, vector<string> > wr;
map<string, int> dp;

void init(){
  
  item.clear(); dp.clear();
  map<string, vector<string> >::iterator it;
  for(it = wr.begin(); it != wr.end(); it++){
    it->second.resize(0);
  }
  wr.clear();

}

int find(string s){
  
  int ret = 0;
  bool judge = false;
  if(dp[s]) return dp[s];
  map<string, vector<string> >::iterator it;
  for(it = wr.begin(); it != wr.end(); it++){
    if(it->first == s){
      for(int i = 0; i < it->second.size(); i++){
	ret += find(it->second[i]);
      }
      judge = true;
      break;
    }
  }
  return dp[s] = min((judge ? ret : INF), (item.find(s) == item.end() ? INF : item[s]));

}

int main(){
  
  int n, m; string trg;
  while(cin >> n, n){
    init();
    for(int i = 0; i < n; i++){
      string s; int v; cin >> s >> v;
      item[s] = v;
    }
    cin >> m;
    for(int i = 0; i < m; i++){
      string s; int v; cin >> s >> v;
      for(int j = 0; j < v; j++){
	string name; cin >> name;
	wr[s].push_back(name);
      }
    }
    cin >> trg;
    cout << find(trg) << endl;
  }

}

C++: // 2014/10/27 Tazoe

#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;

int min_cost(string r, map<string, int>& itm, map<string, vector<string> >& rcp)
{
	if(rcp.find(r)==rcp.end())
		return itm[r];

	int sum = 0;
	for(int i=0; i<rcp[r].size(); i++){
		sum += min_cost(rcp[r][i], itm, rcp);
	}

	if(sum<itm[r])
		return sum;
	else
		return itm[r];
}

int main()
{
	while(true){
		int n;
		cin >> n;

		if(n==0)
			break;

		map<string, int> itm;
		for(int i=0; i<n; i++){
			string s;
			int p;
			cin >> s >> p;

			itm[s] = p;
		}

		int m;
		cin >> m;

		map<string, vector<string> > rcp;
		for(int i=0; i<m; i++){
			string o;
			int k;
			cin >> o >> k;

			for(int j=0; j<k; j++){
				string q;
				cin >> q;

				rcp[o].push_back(q);
			}
		}

		string r;
		cin >> r;

		cout << min_cost(r, itm, rcp) << endl;
	}

	return 0;
}

C++: #include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#define mp make_pair
using namespace std;

map<string,vector<string> > recipe;
map<string,int>items;

int price(string item){
  if(recipe.find(item) != recipe.end()){
    int p=0;
    for(int i=0;i<recipe[item].size();i++)
      p+= price(recipe[item][i]);
    return min(p,items[item]);
  }
  else return items[item];
}

int main(){
  int n,m,k;
  while(true){
    cin>>n;
    if(!n)break;
    string name;
    int pr;
    items.clear();
    recipe.clear();
    for(int i=0;i<n;i++){
      cin>>name>>pr;
      items.insert(mp(name,pr));
    }
    cin>>m;
    for(int j=0;j<m;j++){
      cin>>name>>k;
      vector<string> material;
      string mat_name;
      for(int i=0;i<k;i++){
	cin>>mat_name;
	material.push_back(mat_name);
      }
      recipe.insert(mp(name,material));
    }
    cin>>name;
    cout<<price(name)<<endl;
  }
  return 0;
}