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>
using namespace std;
pair<string, int>X[1000];
vector<int>Y[1000];
int dp[1000];
int N, M, C, Q; string S;
int main() {
	while (true) {
		for (int i = 0; i < 1000; i++) {
			dp[i] = 0;
			Y[i].clear();
			X[i] = make_pair("", 0);
		}
		cin >> N;
		if (N == 0) { break; }
		for (int i = 0; i < N; i++) {
			cin >> X[i].first >> X[i].second;
			dp[i] = X[i].second;
		}
		cin >> M;
		for (int i = 0; i < M; i++) {
			cin >> S;
			for (int j = 0; j < N; j++) {
				if (S == X[j].first) {
					C = j;
				}
			}
			cin >> Q;
			for (int j = 0; j < Q; j++) {
				cin >> S;
				for (int k = 0; k < N; k++) {
					if (X[k].first == S) {
						Y[C].push_back(k);
					}
				}
			}
		}
		for (int i = 0; i < N * 2; i++) {
			for (int j = 0; j < N; j++) {
				int sum = 0;
				if(Y[j].size()==0){
					continue;
				}
				for (int k = 0; k < Y[j].size(); k++) {
					sum += dp[Y[j][k]];
				}
				if (dp[j] > sum) {
					dp[j] = sum;
				}
			}
		}
		cin >> S;
		for (int i = 0; i < N; i++) {
			if (S == X[i].first) {
				C = i;
			}
		}
		cout << dp[C] << endl;
	}
	return 0;
}

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

template<class T> inline void chmin(T &a, const T &b) { if(a > b) a = b; }

typedef vector<vector<int>> graph;

void dfs(int v, const graph &G, vector<bool> &visited, vector<int> &order) {
	visited[v] = true;
	for(const auto &to : G[v]) {
		if(!visited[to]) dfs(to, G, visited, order);
	}
	order.emplace_back(v);
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	for(int n; cin >> n && n;) {
		unordered_map<string, int> encoder;
		vector<int> price(n);

		for(int i = 0; i < n; ++i) {
			string name;
			cin >> name >> price[i];
			encoder[name] = i;
		}

		int m;
		cin >> m;

		graph G(n);
		for(int i = 0; i < m; ++i) {
			string target;
			int k;
			cin >> target >> k;

			const int to = encoder[target];
			for(int j = 0; j < k; ++j) {
				string from;
				cin >> from;
				G[encoder[from]].emplace_back(to);
			}
		}

		vector<bool> visited(n, false);
		vector<int> order;
		for(int v = 0; v < n; ++v) {
			if(!visited[v]) dfs(v, G, visited, order);
		}

		vector<int> sum(n, INT_MAX);
		for(int i = n - 1; i >= 0; --i) {
			const int v = order[i];
			chmin(sum[v], price[v]);

			for(const auto &to : G[v]) {
				if(sum[to] == INT_MAX) sum[to] = 0;
				sum[to] += sum[v];
			}
		}

		string want;
		cin >> want;
		cout << sum[encoder[want]] << endl;
	}

	return EXIT_SUCCESS;
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <sstream>
#include <cmath>
#include <queue>

using namespace std;

vector<int> tree[200];
int cost[200];

int min_cost(int index){
	if(tree[index].size() == 0){
		return cost[index];
	}
	int sum = 0;
	int siz = tree[index].size();
	for(int i = 0; i < siz; i++){
		sum += min_cost(tree[index].at(i));
	}
	return min(sum, cost[index]);
}

int main(){
	
	string name[200];
	
	int n, m;
	
	while(true){
		
		cin >> n;
		
		if(n == 0){
			break;
		}
		
		for(int i = 0; i < n; i++){
			cin >> name[i] >> cost[i];
			tree[i].erase(tree[i].begin(), tree[i].end());
		}
		
		cin >> m;
		
		for(int i = 0; i < m; i++){
			string str;
			int num;
			cin >> str >> num;
			int index = 0;
			for(int j = 0; j < n; j++){
				if(str == name[j]){
					index = j;
					break;
				}
			}
			for(int j = 0; j < num; j++){
				string str2;
				cin >> str2;
				for(int k = 0; k < n; k++){
					if(str2 == name[k]){
						tree[index].push_back(k);
						break;
					}
				}
			}
		}
		
		string str;
		cin >> str;
		int index;
		
		for(int i = 0; i < n; i++){
			if(str == name[i]){
				index = i;
				break;
			}
		}
		
		cout << min_cost(index) << endl;
		
	}
	
	return 0;
}

C++: #include<iostream>
#include<string>
#include<algorithm>
#include<utility>
#include<vector>
using namespace std;
typedef pair<string, int>P;

int main() {
	int n;
	while (cin >> n, n) {
		vector<P>v;
		for (int i = 0;i < n;i++) {
			string sa, int a;
			cin >> sa >> a;
			v.push_back(P(sa, a));
		}

		int m;
		cin >> m;
		for (int i = 0;i < m;i++) {
			string s;
			cin >> s;
			int a;
			cin >> a;

			int it=-1;
			int mny = 0;
			for (int j = 0;j < a;j++) {
				string sb;
				cin >> sb;
				for (int k = 0;k < n;k++) {
					if (sb == v[k].first) {
						mny += v[k].second;
					}
				}
			}
			for (int j = 0;j < v.size();j++) {
				if (s == v[j].first)it = j;
			}
			if (it == -1)v.push_back(P(s, mny));
			else v[it].second = mny;
		}

		string ans;
		cin >> ans;
		for (int i = 0;i < v.size();i++) {
			if (ans == v[i].first) {
				cout << v[i].second << endl;
				break;
			}
		}
	}
	return 0;
}