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[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]] = conv.size() - 1;
		REP(i, M) {
			if (conv.find(O[i]) == conv.end()) conv[O[i]] = conv.size() - 1;
			REP(j, K[i]) if (conv.find(Q[i][j]) == conv.end()) conv[Q[i][j]] = 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]);
		
		REP(i, N) if (cost[i] == INF) assert(false);
		
		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<vector>
#include<map>

const int infty = 1<<29;
using namespace std;

int minimumCost(string need,
		map<string,int> &matval,
		map<string,vector<string> > &wrought)
{
  int ret = matval[need];
  
  int S = 1<<wrought[need].size();
  for(int i = 1; i < S; ++i){
    int cost = 0;
    for(int j = 0; j < wrought[need].size(); ++j){
      if( i & (1<<j) ){
	cost += minimumCost( wrought[need][j], matval, wrought );
      }else{
	cost += matval[ wrought[need][j] ];
      }
    }
    ret = min( ret, cost );
  }

  return ret;
}

int main()
{
  while(true){
    int n;
    cin >> n;
    map<string,int> material;
    map<string,vector<string> > wrought;

    if(n==0)break;
    for(int i = 0; i < n; ++i){
      string s;
      int val;
      cin >> s >> val;
      material[s]=val;
    }
    int m;
    cin >> m;
    for(int i = 0; i < m; ++i){
      string s;
      cin >> s;
      int num;
      cin >> num;
      for(int j = 0; j < num; ++j){
	string mat;
	cin >> mat;
	wrought[s].push_back(mat);
      }
    }
    string needed;
    cin >> needed;

    cout << minimumCost( needed, material, wrought ) << endl;
    
  }
  return 0;

}

C++: #include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <algorithm>
int n;

struct item{
    string name[256];
    int cost;
    vector<string> used;
    int size;
} ;

item list[100];
int memo[100];

int getCost(int v)
{
    if(memo[v]!=-1)return memo[v];
    int i, j;
    int ans;
    
    if (list[v].size == 0){
        return (list[v].cost);
    }
    else {
        ans = 0;
        for (i = 0; i < list[v].size; i++){
            for (j = 0; j < n; j++){
                if (list[v].used[i]== list[j].name){
                    ans += getCost(j);
                }
            }
        }
        list[v].cost = min(list[v].cost,ans);
    }
    return (list[vertex].cost);
}

int main(void)
{
    int i, j, k;
    int m, kk;
    string key, temp;
    int look, sum;
    
    while (1){
        scanf("%d", &n);
        
        if (n == 0){
            break;
        }
        for(i=0;i<n;i++)memo[i]=-1;
        for (i = 0; i < n; i++){
            cin >> list[i].name >> list[i].cost;
            list[i].size = 0;
        }
        
        cin >> m;
        for (i = 0; i < m; i++){
            cin >> key;
            for (j = 0; j < n; j++){
                if (key==list[j].name){
                    look = j;
                }
            }
            cin >> kk;
            list[look].size = kk;
            for (j = 0; j < kk; j++){
                cin >> temp;
                for (k = 0; k < n; k++){
                    if (temp==list[k].name){
                        list[look].used[j]=temp;
                    }
                }
            }
        }
        cin >> key;
        for (j = 0; j < n; j++){
            if (strcmp(key, list[j].name) == 0){
                look = j;
            }
        }
        
        cout << getCost(look);
        
    }
    
    return (0);
}

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

map<string,int> price;
map<string,vector<string> > mix;

int res(string s){
	if(!mix.count(s))return price[s];
	int ans=0;
	for(int i=0;i<mix[s].size();i++){
		ans+=res(mix[s][i]);
	}
	if(price[s]>ans)price[s]=ans;
	return price[s];
}

int main(){
	int n,b,c;
	string a,d;
	while(cin>>n,n){
		price.clear();mix.clear();
		for(int i=0;i<n;i++){
			cin>>a>>b;
			price[a]=b;
		}
		cin>>c;
		for(int i=0;i<c;i++){
			cin>>a>>b;
			for(int i=0;i<b;i++){
				cin>>d;
				mix[a].push_back(d);
			}
		}
		cin>>d;
		cout<<res(d)<<endl;
	}
}

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

int min( long int a, long int b )
{
    if( a < b )
        return a;
    else
        return b;
}

int main()
{
    int n, m, k;
    string str, s[100];
    map<string,int> a;
    
    while( cin >> n )
    {
        if( n == 0 )
            break;

        for( int i = 0; i < n; i++ )
        {
            cin >> str >> m;
            a[str] = m;
        }

        cin >> m;

        for( int i = 0; i < m; i++ )
        {
            cin >> str >> k;
            long int sum = 0;
            for( int j = 0; j < k; j++ )
            {
                cin >> s[j];
                sum += a[s[j]];
            }
            a[str] = min( a[str], sum );
        }

        cin >> str;

        cout << a[str] << endl;
    }
    
    return 0;
}