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;

struct Node {
    int cost;
    vector<string> to;
};

map<string, Node> price;

int solve(string item) {

    if(price[item].to.size() == 0) return price[item].cost;

    int sum = 0;
    for(int i = 0; i < price[item].to.size(); ++i) {
        sum += solve(price[item].to[i]);
    }

    return min(price[item].cost, sum);

}

int main() {

    int n, m, p, k;
    string s, o, q, t;

    while(cin >> n, n) {

        for(map<string, Node>::iterator it = price.begin(); it != price.end(); ++it) {
            vector<string> &to = it->second.to;
            to.erase(to.begin(), to.end());
        }

        for(int i = 0; i < n; ++i) {
            cin >> s >> p;
            price[s].cost = p;
        }

        cin >> m;

        for(int i = 0; i < m; ++i) {
            cin >> o >> k;
            for(int j = 0; j < k; ++j) {
                cin >> q;
                price[o].to.push_back(q);
            }
        }

        cin >> t;

        cout << solve(t) << endl;

    }

}

C++: #include <iostream>
#include <complex>
#include <sstream>
#include <string>
#include <algorithm>
#include <deque>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <limits>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
#define REP(i, j) for(int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for(int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;

int N, M;

int solve(string tar, map<string, int> &item, map<string, vector<string> > &recipe){
  if(recipe.find(tar) == recipe.end()) return item[tar];
  int res = item[tar], sum = 0;
  REP(i, recipe[tar].size()) sum += solve(recipe[tar][i], item, recipe);
  return min(res, sum);
}

int main() {
  while(cin >>N && N){
    map<string, vector<string> > recipe;
    map<string, int> item;
    REP(i, N){
      string s; int n; cin >>s >>n;
      item[s] = n;
    }
    cin >>M;
    REP(i, M){
      string s; cin >>s;
      int n; cin >>n;
      recipe[s] = vector<string>(n);
      REP(j, n){
        string t; cin >>t;
        recipe[s][j] = t;
      }
    }
    string tar; cin >>tar;
    cout <<solve(tar, item, recipe) <<endl;
  }
  return 0;
}

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

struct Item{
  string name;

  int cost;
};

struct recipe{
  vector<string> needs;
  string product;
};

int main() {
  int n;
  while(1){
    cin>>n;
    if(n==0)break;

    string name;
    int cost;
    vector<Item> itemlist;
    Item item;

    while(n--){
      cin>>name>>cost;
      item.name=name;
      item.cost=cost;
      itemlist.push_back(item);
    }

    cin>>n;

    int num;
    recipe r;
    vector<recipe> repices;

    while(n--){
      cin>>name>>num;
      r.product=name;
      r.needs.clear();

      while(num--){
	cin>>name;
	r.needs.push_back(name);
      }

      repices.push_back(r);
    }

    for(int p=0; p<repices.size(); p++){
      for(int i=0; i<repices.size(); i++){
	int t=0;

	for(int j=0; j< repices[i].needs.size(); j++){
	  for(int k=0; k<itemlist.size(); k++){
	    if(repices[i].needs[j] == itemlist[k].name) {
	      t+=itemlist[k].cost;
	    }
	  }
	}

	for(int j=0; j < itemlist.size(); j++)
	  if(repices[i].product == itemlist[j].name && t < itemlist[j].cost)
	    itemlist[j].cost = t,t=0;
      }
    }

    cin>>name;

    for(int j=0; j < itemlist.size(); j++){
      if(itemlist[j].name == name ) cout<<itemlist[j].cost<<endl;
    }

  }
}

C++: #include <iostream>
#include <unordered_map>
#include <vector>
#include <bitset>
#include <utility>
using namespace std;
#define MP make_pair
#define F first
#define S second
#define PB push_back
const int N=100 + 10;
int main(){
    int n,k,val[N],now,q,temp;
    bitset<N>b;
    bool f,c;
    string s;
    unordered_map<string,int> m;
    vector<vector<int>>graph[N];
    vector<int> emp;
    while(true){
        cin>>n;
        if(n==0)return 0;
        b.reset();
        m.clear();
        for(int i=0;i<n;i++){
            cin>>s>>k;
            m.insert(MP(s,i));
            val[i]=k;
        }
        cin>>q;
        for(int i=0;i<q;i++){
            cin>>s>>k;
            now=m[s];
            b[now]=true;
            graph[now].PB(emp);
            while(k--){
                cin>>s;
                graph[now].back().PB(m[s]);
            }
        }
        while(q){
            for(int i=0;i<n;i++)if(!graph[i].empty()){
                f=true;
                for(int j=0;j<graph[i].size();j++)if(!graph[i][j].empty()){
                    f=false;
                    c=true;
                    temp=0;
                    for(int r=0;r<graph[i][j].size();r++){
                        if(b[graph[i][j][r]]){
                            c=false;
                            break;
                        }
                        else temp+=val[graph[i][j][r]];
                    }
                    if(c){
                        val[i]=min(val[i],temp);
                        graph[i][j].clear();
                        q--;
                    }
                }
                if(f){
                    graph[i].clear();
                    b[i]=false;
                }
            }
        }
        cin>>s;
        cout<<val[m[s]]<<endl;
    }
    
}

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

const int MOD = 1e9 + 7;
const int iINF = 1000000000;
const long long int llINF = 1000000000000000000;
const double PI = acos(-1.0);
#define rep(i, n) for (int i = 0; i < (n); i++)

using namespace std;
using ll = long long int;
using P = pair<int, int>;
using T = tuple<int, int, int>;
using edge = struct
{
    int to;
    int cost;
};

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main()
{
    int N;
    while(cin >> N && N)
    {
        map<string, ll> mp;
        rep(i, N)
        {
            string s;
            int p;
            cin >> s >> p;

            mp[s] = p;

        }

        int M;
        cin >> M;

        rep(i, M)
        {
            int num;
            ll sum = 0;
            string maked;
            cin >> maked >> num;

            rep(i, num)
            {
                string mat;
                cin >> mat;
                sum += mp[mat];
            }

            mp[maked] = min(sum, mp[maked]);
        }

        string t;
        cin >> t;

        cout << mp[t] << endl;

    }
    
    return 0;
}