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<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;
    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;
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
int main(){
  int n;
  map<string, int> items;
  string name;
  int value;
  
  while(cin >> n, n){
    items.clear();
    
    for(int i = 0 ; i < n ; i++){
      cin >> name >> value;
      items.insert(make_pair(name, value));
    }
    int m;
    int total;
    string names;
    cin >> n;
    for(int i = 0 ; i < n ; i++){
      total = 0;
      cin >> name;
      cin >> m;
      for(int j = 0 ; j < m ; j++){
	cin >> names;
	total += items[names];
      }
      items[name] = min(items[name], total);
    }
    cin >> name;
    cout << items[name] << endl;
  }
  return 0;
}

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

using namespace std;

map<string,int> dp;
map<string,int> buy;
map<string, vector<string> > reci;

const int INF = 1000000;

#define rep(i,a) for(int i=0; i<(a); i++)

int solve(string to){
  int ari = 0;
  rep(i,reci[to].size()){
    ari += solve(reci[to][i]);
  }
  if(ari == 0){
    ari = buy[to];
  }
  
  int rtn = min(ari, dp[to]);
  dp[to] = rtn;
  return rtn;
}


int main(){
  int n;
  while(cin >> n, n){
    rep(i,n){
      string str; int p;
      cin >> str >> p;
      buy[str] = p;
      dp[str] = INF;
    }
    int r; cin >> r;
    rep(i,r){
      string str; int m;
      cin >> str >> m;
      rep(j,m){
	string ing;
	cin >> ing;
	reci[str].push_back(ing);
      }
    }

    // solve

    string to; cin >> to;
    cout << solve(to) << endl;
  }
  return 0;
}

C++: #include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#define INF 999999999
using namespace std;
std::map<string,int> z;
std::map<string,vector<string> > l;
int n;
int m;

int saisyo(string str){
	int ans=INF;
	if(z.count(str)!=0)ans=z[str];
	if(l.count(str)==0)return ans;
	int sum=0;
	for(int i=0;i<l[str].size();i++){
		sum+=saisyo(l[str][i]);
	}
	return min(ans,sum);
}

int main(void){
	while(cin>>n,n){
		z.clear();l.clear();
		string s;
		int v;
		for(int i=0;i<n;i++){
			cin>>s>>v;
			z[s]=v;
		}
		cin>>m;
		for(int i=0;i<m;i++){
			cin>>s>>v;
			string s2;
			for(int j=0;j<v;j++){
				cin>>s2;
				l[s].push_back(s2);
			}
		}
		cin>>s; //search
	cout<<saisyo(s)<<endl;
	}
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
int n;
main()
{
	while(cin>>n,n)
	{
		map<string,int>M;
		map<string,vector<string> >A;
		map<string,int>cnt;
		for(int i=0;i<n;i++)
		{
			string s;int a;cin>>s>>a;M[s]=a;
			cnt[s]=0;
		}
		int m;cin>>m;
		for(int i=0;i<m;i++)
		{
			string s;cin>>s;
			int k;cin>>k;
			for(;k--;)
			{
				string t;cin>>t;
				A[s].push_back(t);
				cnt[s]++;
			}
		}
		vector<pair<int,string> >a;
		for(pair<string,int>it:M)
		{
			a.push_back(make_pair(it.second,it.first));
		}
		sort(a.begin(),a.end());
		for(int i=0;i<n;i++)
		{
			string s=a[i].second;
			if(cnt[s]==0)continue;
			int now=0;
			for(int j=0;j<cnt[s];j++)now+=M[A[s][j]];
			M[s]=min(M[s],now);
		}
		string s;cin>>s;
		cout<<M[s]<<endl;
	}
}

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

int main()
{
	int n;
	while( cin >> n && n ){
		map< string, int > nameList;
		vector< long long int > valueList( n, 0 );
		for( int i = 0; i < n; ++i ){
			string s;
			int v;
			cin >> s >> v;
			nameList.insert( make_pair( s, i ) );
			valueList[ i ] = v;
		}
		int m;
		vector< vector< int > > recipeList( n, vector< int >() );
		cin >> m;
		for( int i = 0; i < m; ++i ){
			string o;
			int k;
			cin >> o >> k;
			map< string, int >::iterator itr = nameList.find( o );
			if( itr == nameList.end() ){
				continue;
			}
			int productId = itr->second;
			for( int j = 0; j < k; ++j ){
				string q;
				cin >> q;
				itr = nameList.find( q );
				if( itr == nameList.end() ){
					recipeList[ productId ] = vector< int >();
					break;
				}
				int materialId = itr->second;
				recipeList[ productId ].push_back( materialId );
			}
		}
		vector< int > depthList( n, -1 );
		queue< int > updateList;
		for( int i = 0; i < n; ++i ){
			updateList.push( i );
		}
		while( !updateList.empty() ){
			int id = updateList.front();
			updateList.pop();
			if( recipeList[ id ].empty() ){
				depthList[ id ] = 0;
				continue;
			}
			int size = recipeList[ id ].size();
			int d = -1;
			for( int i = 0; i < size; ++i ){
				int materialDepth = recipeList[ id ][ i ];
				if( materialDepth == -1 ){
					d = -1;
					break;
				}
				d = max( d, materialDepth );
			}
			if( d > -1 ){
				depthList[ id ] = d + 1;
			}else{
				updateList.push( id );
			}
		}
		vector< pair< int, int > > sortedList;
		for( int i = 0; i < n; ++i ){
			sortedList.push_back( make_pair( depthList[ i ], i ) );
		}
		sort( sortedList.begin(), sortedList.end() );

		for( int i = 0; i < (int)sortedList.size(); ++i ){
			int id = sortedList[ i ].second;
			vector< int > recipe = recipeList[ id ];
			if( recipe.empty() ){
				continue;
			}
			long long int value = 0;
			for( int j = 0; j < (int)recipe.size(); ++j ){
				value += valueList[ recipe[ j ] ];
			}
			if( value < valueList[ id ] ){
				valueList[ id ] = value;
			}
		}

		string ansName;
		cin >> ansName;
		cout << valueList[ nameList.find( ansName )->second ] << endl;
	}
	return 0;
}