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 <stdio.h>
#include <queue>
#include <string.h>
using namespace std;
typedef pair<int,int> P;

//howmuch[i]:i番のアイテムの最小の値段
int howmuch[100];

//itemname[i]:i番目のアイテムの名前
char itemname[100][101];

//n:アイテムの種類 m:レシピの数
int n,m;

//resipeuseditem[i][k]:iをつくるためにkを用いたかどうかの判定
bool resipeuseditem[100][100];

//resipeN[i]:iを作るために用いたアイテムの番号を保存する
queue <int> resipeN[100];

//allminseek作業用キュー
priority_queue< P,vector<P>,greater<P> > que;

//アイテム名を番号に変換する関数
int nameTOnonber(char *);

//最小値を求める
void allminseek();

int main()
{
	int k,i,j,oTOi,o2;
	char o[101];

	scanf("%d",&n);

	while(n != 0){
	//初期化
	for(i = 0; i < 100; i++){
		for(j = 0; j < 100; j++){
			resipeuseditem[i][j] = false;
		}
	}

	//入力
	for(i = 0;i < n; i++){
		fflush(stdin);
		scanf("%s %d",itemname[i],&howmuch[i]);
		int a = nameTOnonber(itemname[i]);
		que.push(P(howmuch[i],a));
	}

	scanf("%d",&m);
	for(i = 0;i < m; i++){
		scanf("%s %d",o,&k);
		oTOi = nameTOnonber(o);
		//printf("k:%d\n",k);
		for(j = 0; j < k; j++){
			scanf("%s",o);
			o2 = nameTOnonber(o);
			resipeN[oTOi].push(o2);
			resipeuseditem[oTOi][o2] = true;
			//printf("作るもの:%d 素材[%d]:%d\n",oTOi,j,o2);
		}
		//printf("size:%d\n",resipeN[oTOi].size());
	}
	
	//探索
	allminseek();

	scanf("%s",o);
	printf("%d\n",howmuch[ nameTOnonber(o) ]);

	scanf("%d",&n);
	}
	return 0;
}

int nameTOnonber(char *name){
	for(int i = 0; i < n; i++){
		if(strcmp(itemname[i],name) == 0){
			//printf("アイテム名:%s 配列番号:%d\n",name,i);
			return i;
		}
	}

	printf("nameTOnonber変換ミス\n");
	return INT_MAX;
}

void allminseek(){

	//アイテムiを使用したかどうかのフラグ
	bool used[100];
	int temp,minNO;

	//printf("min:配列%d 値段%d",min.first,min.second);
	for(int i = 0; i < n; i++)	used[i] = false;

	while(!que.empty()){
		minNO = que.top().second;
		que.pop();
		//printf("最小値段アイテム:%s\n",itemname[minNO]);
		if(!used[ minNO ]){
			//minNOを使用しているレシピの探索と実行
			for(int i = 0;i < n; i++){
				//printf("[%d][%d]%d\n",i,minNO,resipeuseditem[i][minNO]);
				if(resipeuseditem[i][minNO]){
					temp = 0;
					for(int j = 0; j < resipeN[i].size(); j++){
						temp += howmuch[ resipeN[i].front() ];
						//printf("材料:%d 値段:%d 合計:%d\n",resipeN[i].front(),howmuch[ resipeN[i].front() ],temp);
						resipeN[i].push(resipeN[i].front());
						resipeN[i].pop();
					}
					if(howmuch[i] > temp){
						howmuch[i] = temp;
						que.push(P(temp,i));
					}
				}
			}
			
			used[ minNO ] = true;
		}
	}
}

C++: #include <bits/stdc++.h>
using namespace std;

struct recipe{
	string item;
	int n;
	string* items;
	int min;
};


int main(){
	int n , m , j , k;
	string want;
	while(cin >> n , n){
		vector< pair<string , int> > item(n);
		for(int i=0;i<n;++i){
			cin >> item[i].first >> item[i].second;
		}
		cin >> m;
		recipe* r = new recipe [m];
		for(int i=0;i<m;++i){
			cin >> r[i].item >> r[i].n;
			r[i].items = new string [r[i].n];
			for(j=0;j<r[i].n;++j){
				cin >> r[i].items[j];
			}
		}
		cin >> want;
		
		int mn,dir;
		for(int i=0 ;i<m ;++i){
		mn=dir=0;
			string tmp1=r[i].item;
			for(j=0;j<r[i].n ;++j){
				string tmp2=r[i].items[j];
				for(k=0;k<n;++k){
					if(tmp2==item[k].first){
						mn+=item[k].second;
						break;
					}
				}
			}
			for(k=0;k<n;++k){
				if(tmp1==item[k].first){
					dir=item[k].second; //??´??\?????\
					break;
				}
			}
			
			r[i].min=min(mn , dir);
		}
		mn=dir=0;
		string tmp;
		for(int i=0;i<m;++i){ 
			if(want==r[i].item){ 
				for(j=0;j<r[i].n ;++j){
					tmp=r[i].items[j];
					for(k=0;k<m;++k){
						if(tmp==r[k].item){
							mn+=r[k].min;
							break;
						}
					}
					if(k==m){
						for(int l=0;l<n;++l){
							if(tmp==item[l].first){
								mn+=item[l].second;
								break;
							}
						}
					}
				}
					if(mn==0){ //??¬?????¬???????????????????????£???
						for(int i=0 ; i<n ;++i){
							if(want==item[i].first){ 
								mn=item[i].second;  //??´??\?????\
								break;
							}
						}
						
					}
			}	
		}
		cout << mn << endl;
		
		for(int i=0;i<m;++i){
			delete [] r[i].items;
		}
		delete [] r;
	}	
	return 0;
}

C++: #include<cstdio>
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<algorithm>

using namespace std;

int main(){
	bool sosuu[1000001];
	bool dp[1000001];
	
	while(1){
		for(int i=0;i<=1000000;i++){
			sosuu[i]=0;
			dp[i]=0;
		}
		for(int i=2;i<=500000;i++){
			if(sosuu[i]==0){
				for(int j=i;j<=1000000;j+=i){
					sosuu[j]=1;
				}
				sosuu[i]=0;
			}
		}
		sosuu[0]=1;
		sosuu[1]=1;
		
		int item[30];
		
		int n,m;
		scanf("%d%d",&n,&m);
		
		if(n==0 && m==0){
			break;
		}
		for(int i=0;i<n;i++){
			scanf("%d",&item[i]);
		}
		dp[0]=1;
		for(int i=0;i<=m;i++){
			for(int j=0;j<n;j++){
				if(i<item[j]){
					continue;
				}
				if(dp[i-item[j]]==1){
					dp[i]=1;
				}
			}
		}
		int num=0;
		for(int i=m;i>=0;i--){
			if(dp[i]==1&&sosuu[i]==0){
				num=i;
				break;
			}
		}
		if(num==0){
			puts("NA");
		}else{
			printf("%d\n",num);
		}
	}
}

C++: #include <bits/stdc++.h>
using namespace std;
int main() {
	int n,m;
	while(cin>>n&&n){
		map<string,int> data;
		string s;
		int a;
		for(int i=0;i<n;i++){
			cin>>s>>a;
			data[s]=a;
		}
		cin>>m;
		string wrought[100][100];
		int k,sum;
		for(int i=0;i<m;i++){
			cin>>wrought[i][0];
			sum=0;
			cin>>k;
			for(int j=0;j<k;j++){
				cin>>wrought[i][j+1];
				sum+=data[wrought[i][j+1]];
			}
			if(data[wrought[i][0]]>sum)data[wrought[i][0]]=sum;
		}
		for(int i=0;i<m;i++){
			int sum=0;
			for(int j=0;j<k;j++)sum+=data[wrought[i][j+1]];
			if(data[wrought[i][0]]>sum)data[wrought[i][0]]=sum;
		}
		string ans;
		cin>>ans;
		cout<<data[ans]<<endl;
	}
}