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 <map>
using namespace std;

map<string, int> p;
map<string, int> k;
map<string, string*> q;

int min(string item) {
  int buy = p[item];
  if (q.find(item) != q.end()) {
    int trn = 0;
    for (int j=0; j<k[item]; j++) {
      trn += min(q[item][j]);
    }
    if (trn < buy) {
      return trn;
    }
  }
  return buy;
}

int main(void) {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) {
      break;
    }
    for (int j=0; j<n; j++) {
      string i;
      cin >> i;
      cin >> p[i];
    }
    int m;
    cin >> m;
    for (int j=0; j<m; j++) {
      string o;
      cin >> o;
      cin >> k[o];
      q[o] = new string[k[o]];
      for (int l=0; l<k[o]; l++) {
	cin >> q[o][l];
      }
    }
    string item;
    cin >> item;
    cout << min(item) << endl;
    if (!q.empty()) {
      for (map<string, string*>::iterator j=q.begin(); j!=q.end(); j++) {
	delete[] j->second;
      }
      q.clear();
    }
  }
  return 0;
}

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

using namespace std;

int n;
int m;
int ini;
string ins;
map<string,long long> item;
vector<string> change[200];

int minmoney(string ss){
	int mm=item[ss];
	for(int i=0;i<m;i++){
		if(change[i][0]==ss){
			int cm=0;
			for(int j=1;j<change[i].size();j++){
				cm+=minmoney(change[i][j]);
			}
			if(cm<mm) item[ss]=cm;
		}
	}
	return item[ss];
}

int main(){

	
	

	while(1){

		cin>>n;
		if(n==0) break;

		if(!item.empty()) item.clear();
		for(int i=0;i<200;i++){
			if(!change[i].empty()) change[i].clear();
		}

		for(int i=0;i<n;i++){
			cin>>ins>>ini;
			item[ins]=ini;
		}

		cin>>m;

		for(int i=0;i<m;i++){
			cin>>ins;
			change[i].push_back(ins);
			cin>>ini;
			for(int j=0;j<ini;j++){
				cin>>ins;
				change[i].push_back(ins);
			}
		}

		cin>>ins;

		cout<<minmoney(ins)<<endl;

	}
}

C++: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cassert>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
int n;
int main()
{
	while(1)
	{
		cin >> n;
		if(n == 0) return 0;
		map<string,int>hoge;
		int dp[105];
		for(int i=0;i<n;i++)
		{
			string s; int v;
			cin >> s >> v;
			hoge[s] = i;
			dp[i] = v;
		}
		int m;
		cin >> m;
		vector<vector<int> >vec[105];
		for(int i=0;i<m;i++)
		{
			string st; cin >> st;
			int n;
			cin >> n;
			int t = hoge[st];
			vector<int>c;
			for(int j=0;j<n;j++)
			{
				string a;
				cin >> a;
				c.pb(hoge[a]);
			}
			vec[t].pb(c);
		}
		
		while(1)
		{
			bool upd = false;
			for(int i=0;i<n;i++)
			{
				for(int j=0;j<vec[i].size();j++)
				{
					int cnt = 0;
					for(int k=0;k<vec[i][j].size();k++) cnt += dp[vec[i][j][k]];
					if(cnt < dp[i])
					{
						dp[i] = cnt;
						upd = true;
					}
				}
			}
			if(!upd) break;
		}
		string t; cin >> t;
		cout << dp[hoge[t]] << endl;
	}
}

C++: #include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <vector>
using namespace std;
int n;
map<string,int> t;
int c[111];
vector<int> v[111];

int solve(int m){
  int sum = 0;
  if(v[m].empty()) return c[m];
  for(int i = 0; i < (int)v[m].size(); i++){
    sum += solve(v[m][i]);
  }
  return min(sum,c[m]);
}

int main(void){
  while(cin >> n && n){
    t.clear();
    for(int i = 0; i < 111; i++) v[i].clear();
    while(n--){
      string s;
      int a;
      cin >> s >> a;
      t[s] = n;
      c[n] = a;
    }
    cin >> n;
    while(n--){
      string s;
      int a;
      cin >> s >> a;
      int id = t[s];
      for(int i = 0; i < a; i++){
	cin >> s;
	v[id].push_back(t[s]);
      }
    }
    string s;
    cin >> s;
    cout << solve(t[s]) << endl;
  }
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count etc.
#include <cstdlib>	// require abs
#include <cstdio>	// require printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen

using namespace std;

map <string, int> minC;
map <string, vector <string> > rela;

bool last_item (string item )
{
	return (rela.find(item) == rela.end() );
}

void dfs (string item )
{
	if (last_item (item ) ){
		return;
	} // end if

	map <string, vector <string> >::iterator it = rela.find(item);
	vector <string> r = (*it).second;
	vector <string>::iterator jt = r.begin();

	int sum = 0;
	for (; jt != r.end(); ++jt ){
		dfs ((*jt) );
		sum += minC[(*jt)];
	} // end for
	minC[item] = sum;

}

int main()
{
//	cut here before submit 
//	freopen ("testcase.wgm", "r", stdin );
	int n, m;

	while (cin >> n && n ){
		minC.clear();
		rela.clear();
		for (int i = 0; i < n; ++i ){
			string ite = "";
			int cost;
			cin >> ite >> cost;
			minC[ite] = cost;
		} // end for
		cin >> m;
		for (int i = 0; i < m; ++i ){
			string s = "";
			cin >> s;
			int num;
			cin >> num;
			vector <string> t (num );
			for (int j = 0; j < num; ++j ){
				cin >> t[j];
			} // end for
			rela[s] = t;
		} // end for
		string qns;
		cin >> qns;
		
		dfs (qns );

		cout << minC[qns] << endl;
	} // end loop
		
	return 0;
}