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<cmath>
#include<queue>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<functional>
#include<algorithm>
#include<cstdio>
using namespace std;
int main() {
	int n;
	while (cin >> n&&n != 0) {
		string a[100];
		int b[100];
		bool c[100];
		vector<int>d[100];
		list<int>m2;
		for (int i = 0; i<n; i++) {
			cin >> a[i] >> b[i];
			c[i] = false;
		}
		int m;
		cin >> m;
		for (int i = 0; i<m; i++) {
			string o, q;
			int k;
			cin >> o >> k;
			int e;
			for (e = 0; e<n; e++) {
				if (a[e] == o)
					break;
			}
			c[e] = true;
			m2.push_back(e);
			for (int j = 0; j<k; j++) {
				cin >> q;
				for (int z = 0; z<n; z++) {
					if (a[z] == q) {
						d[e].push_back(z);
						break;
					}
				}
			}
		}
		while (m2.size()>0) {
			list<int>::iterator it = m2.begin(), it2;
			for (int i = 0; i<(int)m2.size();) {
				int e = (*it), sum = 0;
				bool l = true;
				for (int j = 0; j<(int)d[e].size(); j++) {
					if (c[d[e][j]]) {
						l = false;
						goto stop;
					}
					sum += b[d[e][j]];
				}
				b[e] = min(b[e], sum);
				it2 = it;
				it++;
				m2.erase(it2);
				c[e] = false;
			stop:;
				if (!l) {
					it++;
					i++;
				}
			}
		}
		string t;
		cin >> t;
		for (int i = 0; i<n; i++) {
			if (a[i] == t) {
				cout << b[i] << endl;
				break;
			}
		}
	}
}

C++: #include<iostream>
#include<algorithm>
#include<map>
#include<vector>
#include<string>
using namespace std;
typedef struct{
  vector<string> sozai;
  long long money;
}BUTU;
pair<string,logn long> P[1002];
BUTU butu[1024];
long long n,p,m,a,b;
string s,ss,mokuhyou;
long long tansaku(string now){
  for(int i=0;i<n;i++){
    if(P[i].first==now){
      return P[i].second;
    }
  }
  return -1;
}
long long check(string now){
  long long banti=tansaku(now);
  long long f=butu[banti].sozai.size();
  long long cnt=0;
  if(f==0){
    return butu[banti].money;
  }
  else{
    for(int i=0;i<f;i++){
      if(tansaku(butu[banti].sozai[i])!=-1){
	cnt+=check(butu[banti].sozai[i]);
      }
      else{
	return butu[banti].money;
      }
    }
    return min(cnt,butu[banti].money);
  }
  return -1;
}
main(){
  while(1){
    cin>>n;
    if(n==0)break;
    for(int i=0;i<n;i++){
      cin>>s>>p;
      butu[i].money=p;
      P[i].first=s;
      P[i].second=i;
    }
    cin>>m;
    for(int i=0;i<m;i++){
      cin>>s>>a;
      b=tansaku(s);
      for(int j=0;j<a;j++){
	cin>>ss;
	butu[b].sozai.push_back(ss);
      }
    }
    cin>>mokuhyou;
    cout<<check(mokuhyou)<<endl;
  }
}

C++: #include <iostream>
#include <stdio.h>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <set>
#include <math.h>
#include <utility>
#include <stack>
#include <string.h>
using namespace std;
typedef pair<int,int> P;
const int INF = ~(1<<31) / 2;


int n,m;
string name[100];
int cost[100];
map<string, int> nametoi;
vector<vector<int> > g;

int dfs(int v){
    //printf("%d %d\n",v,cost[v]);
    if(g[v].size()!=0){
        int wrought_c = 0;
        for(int i=0;i<g[v].size();i++){
            wrought_c += dfs(g[v][i]);
        }
        cost[v] = min(cost[v],wrought_c);
    }
    return cost[v];
}

int main(){
    while(1){
        scanf("%d", &n);
        if(n==0)break;
        g.clear();
        g.resize(n);
        for(int i=0;i<n;i++){
            cin >> name[i] >> cost[i];
            nametoi[name[i]] = i;
        }

        scanf("%d",&m);
        for(int i=0;i<m;i++){
            string target;
            int e_num;
            cin >> target >> e_num;

            int target_i = nametoi[target];
            for(int j=0;j<e_num;j++){
                string e;
                cin >> e;
                g[target_i].push_back(nametoi[e]);
            }
        }
        string str;
        cin >> str;
        cout << dfs(nametoi[str]) << endl;
    }
    return 0;
}

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

int main(){
	int n;
	while (std::cin>>n,n){
		std::map<std::string, int>items;
		for (int i = 0; i < n; i++){
			std::string str;
			int a;
			std::cin >> str >> a;
			items.insert(std::make_pair(str, a));
		}
		int renkinn;
		std::cin >> renkinn;
		for (int i = 0; i < renkinn; i++){
			std::string item;
			int sum = 0, a;
			std::cin >> item >> a;
			for (int j = 0; j < a; j++){
				std::string b;
				std::cin >> b;
				sum += items[b];
			}
			if (sum < items[item])items[item] = sum;
		}
		std::string ans;
		std::cin >> ans;
		std::cout << items[ans] << std::endl;
	}
	return 0;
}

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