Problem:
Problem D:
Rock Man
You were the master craftsman in the stone age, and you devoted your life to carving many varieties of
tools out of natural stones. Your works have ever been displayed respectfully in many museums, even in
2006 A.D. However, most people visiting the museums do not spend so much time to look at your works.
Seeing the situation from the Heaven, you brought back memories of those days you had frantically lived.
One day in your busiest days, you got a number of orders for making tools. Each order requested one
tool which was different from the other orders. It often took some days to fill one order without special
tools. But you could use tools which you had already made completely, in order to carve new tools more
quickly. For each tool in the list of the orders, there was exactly one tool which could support carving it.
In those days, your schedule to fill the orders was not so efficient. You are now thinking of making the
most efficient schedule, i.e. the schedule for all orders being filled in the shortest days, using the program
you are going to write.
Input
The input consists of a series of test cases. Each case begins with a line containing a single integer
N
which represents the number of ordered tools.
Then
N
lines follow, each specifying an order by four elements separated by one or more space:
name
,
day
1
,
sup
and
day
2
.
name
is the name of the tool in the corresponding order.
day
1
is the number of
required days to make the tool without any support tool.
sup
is the name of the tool that can support
carving the target tool.
day
2
is the number of required days make the tool with the corresponding support
tool.
The input terminates with the case where
N
= 0. You should not process this case.
You can assume that the input follows the constraints below:
N
≤ 1000;
name
consists of no longer than 32 non-space characters, and is unique in each case;
sup
is one of all
names
given in the same case; and
0 <
day
2
<
day
1
< 20000.
Output
For each test case, output a single line containing an integer which represents the minimum number of
days required to fill all
N
orders.
Sample Input
3
gu 20 pa 10
ci 20 gu 10
pa 20 ci 10
2
tool 20 tool 10
product 1000 tool 10
8
fishhook  21 disk     3
mill      14 axe      7
boomerang 56 sundial 28
flint     35 fishhook 5
axe       35 flint   14
disk      42 disk     2
sundial   14 disk     7
hammer    28 mill     7
0
Output for the Sample Input
40
30
113

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
#define SHOWA(x,n) for( int yui = 0; yui < n; yui++ ){ cout << x[yui] << " "; } cout << endl

#define pb emplace_back
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ long long int x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head

int n;
map<string,int> ma;
int cnt;

int c[1010];
int d[1010];
int to[1010];

vi cycle;
mi cs;

int used[1010];

void dfs( int x ){
  used[x] = 1;

  if( used[ to[x] ] == 0 ){
    dfs( to[x] );
  } else if( used[ to[x] ] == 1 ){
    int cur = x;
    do{
      cycle.pb( cur );
      cur = to[cur];
    } while( cur != x );
  }
  
  used[x] = 2;
}

int id( string s ){
  if( ma.find( s ) == ma.end() ){
    return ma[s] = cnt++;
  }
  return ma[s];
}

void solve(){
  ma.clear();
  cnt = 0;
  REP( i , n ){
    int a = id( stin() );
    c[a] = in();
    int b = id( stin() );
    d[a] = in();
    to[a] = b;
  }
  cs.clear();
  REP( i , n ){
    used[i] = 0;
  }
  REP( i , n ){
    if( used[i] == 0 ){
      cycle.clear();
      dfs( i );
      if( SZ(cycle) > 0 ){
        cs.pb( cycle );
      }
    }
  }
  int ans = 0;
  REP( i , n ){
    ans += d[i];
  }
  YYS( v , cs ){
    vi ws(0);
    YYS( w , v ){
      ws.pb( c[w] - d[w] );
    }
    SORT( ws );
    ans += ws[0];
  }
  printf( "%d\n" , ans );
}

int main(){

  while( 1 ){
    n = in();
    if( n == 0 ){
      break;
    }
    solve();
  }
  
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3604
final_rank: 16

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;


struct Dscc {
public:

	//fst:belongs , scd:newedges
	pair<vector<vector<int>>, vector<vector<int>>>get(const vector<vector<int>>&edges) {
		nums.resize(edges.size());
		fill(nums.begin(), nums.end(), -1);
		vector<vector<int>>revedges(edges.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				revedges[j].push_back(i);
			}
		}
		int num = 0;
		for (int i = 0; i < edges.size(); ++i) {
			dfs(i, num, edges);
		}
		vector<int>big(nums.size());
		for (int i = 0; i < nums.size(); ++i) {
			big[nums[i]] = i;
		}
		reverse(big.begin(), big.end());
		unis.resize(edges.size());
		fill(unis.begin(), unis.end(), -1);
		num = 0;
		for (int i = 0; i < big.size(); ++i) {

			dfs2(big[i], num, revedges);
			num++;
		}
		vector<int>nums;
		for (int i = 0; i < unis.size(); ++i) {
			nums.push_back(unis[i]);
		}
		sort(nums.begin(), nums.end());
		nums.erase(unique(nums.begin(), nums.end()), nums.end());


		map<int, int>mp;
		for (int i = 0; i < nums.size(); ++i) {
			mp[nums[i]] = i;
		}
		for (int i = 0; i < unis.size(); ++i) {
			unis[i] = mp[unis[i]];
		}

		vector<vector<int>>belongs(nums.size());
		for (int i = 0; i < unis.size(); ++i) {
			belongs[unis[i]].push_back(i);
		}
		vector<vector<int>>newedges(nums.size());
		for (int i = 0; i < edges.size(); ++i) {
			for (auto j : edges[i]) {
				if (unis[i] != unis[j]) {
					newedges[unis[i]].push_back(unis[j]);
				}
			}
		}
		return make_pair(belongs, newedges);
	}
private:
	vector<int>nums;
	vector<int>unis;


	void dfs(const int id, int &num, const vector<vector<int>>&edges) {
		if (nums[id] != -1)return;
		else {
			nums[id] = -2;
			for (auto i : edges[id]) {
				dfs(i, num, edges);
			}
		}
		nums[id] = num++;
		return;
	}
	void dfs2(const int id, const int &num, const vector<vector<int>>&edges) {
		if (unis[id] != -1)return;
		else {
			unis[id] = -2;
			for (auto i : edges[id])
				dfs2(i, num, edges);
		}
		unis[id] = num;
		return;
	}

}dscc;

int get_id(string st,bool flag=false) {
	static map<string,int>mp;
	static int id=0;
	if (flag) {
		mp.clear();
		id=0;
		return 0;
	}
	if (mp.find(st) == mp.end()) {
		mp[st]=id++;
	}
	return mp[st];
}

int main() {
	while (true) {
		get_id("", true);
		int N;cin>>N;
		if(!N)break;

		vector<int>oris(N);
		vector<int>acomes(N);
		vector<vector<int>>edges(N);

		vector<int>ids(N);
		for (int i = 0; i < N; ++i) {
			string ast;
			int b;
			string cst;
			int d;
			cin>>ast>>b>>cst>>d;
			int a=get_id(ast);
			int c=get_id(cst);

			oris[i]=b;
			acomes[i]=d;
			if(a!=c)edges[c].push_back(a);

			ids[a]=i;
		}

		auto p=dscc.get(edges);

		vector<int>comes(p.second.size());
		for (auto es : p.second) {
			for (auto e : es) {
				comes[e]++;
			}
			
		}

		int ans=accumulate(acomes.begin(),acomes.end(),0);
		for(int i=0;i<p.first.size();++i){
			if(comes[i])continue;
			auto v(p.first[i]);
			int minus_max=-1e9;
			for (auto a : v) {
				minus_max=max(minus_max,acomes[ids[a]]-oris[ids[a]]);
			}
			ans-=minus_max;
		}
		cout<<ans<<endl;
		
	}
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3424
final_rank: 17

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct GROUP{
	vector<int> nodes;
};


struct Info{
	int day1,sup_id,day2;
	char name[33],sup_name[33];
};

int N;
int height[1000],parent[1000],num_in[1000];

Info info[1000];
vector<int> G[1000];
vector<int> reverse_G[1000];

GROUP group[1000];
stack<int> S;

bool check[1000];
int table[1000];

int group_index;

bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}


void dfs(int node_id){
	check[node_id] = true;

	for(int i = 0; i < G[node_id].size(); i++){
		if(!check[G[node_id][i]])dfs(G[node_id][i]);
	}
	S.push(node_id);
}

void reverse_dfs(int node_id){
	check[node_id] = true;

	group[group_index].nodes.push_back(node_id);
	table[node_id] = group_index;

	for(int i = 0; i < reverse_G[node_id].size(); i++){
		if(!check[reverse_G[node_id][i]])reverse_dfs(reverse_G[node_id][i]);
	}
}

void func(){

	for(int i = 0; i < N; i++){
		group[i].nodes.clear();
		G[i].clear();
		reverse_G[i].clear();
	}

	for(int i = 0; i < N; i++){
		scanf("%s %d %s %d",info[i].name,&info[i].day1,info[i].sup_name,&info[i].day2);
	}

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){
			if(strCmp(info[k].name,info[i].sup_name)){
				info[i].sup_id = k;

				if(i != k){
					G[k].push_back(i);
					reverse_G[i].push_back(k);
				}
				break;
			}
		}
	}

	for(int i = 0; i < N;i++)check[i] = false;

	for(int i = 0; i < N;i++){
		if(!check[i])dfs(i);
	}

	for(int i = 0; i < N;i++)check[i] = false;

	group_index = -1;

	while(!S.empty()){
		if(!check[S.top()]){
			group_index++;

			reverse_dfs(S.top());
		}
		S.pop();
	}

	for(int i = 0; i < N; i++)num_in[i] = 0;

	int to_group,min_index,minimum;

	for(int i = 0; i <= group_index; i++){
		for(int k = 0; k < group[i].nodes.size(); k++){
			for(int p = 0; p < G[group[i].nodes[k]].size(); p++){
				to_group = table[G[group[i].nodes[k]][p]];
				if(to_group != i)num_in[to_group]++;
			}
		}
	}

	int ans = 0;

	for(int i = 0; i <= group_index;i++){
		if(group[i].nodes.size() == 1){
			if(num_in[i] == 0){
				ans += info[group[i].nodes[0]].day1;
			}else{
				ans += info[group[i].nodes[0]].day2;
			}
		}else{

			if(num_in[i] == 0){
				min_index = 0;
				minimum = info[group[i].nodes[0]].day1 -info[group[i].nodes[0]].day2;

				for(int k = 1; k < group[i].nodes.size(); k++){
					if(info[group[i].nodes[k]].day1 -info[group[i].nodes[k]].day2 < minimum){
						minimum = info[group[i].nodes[k]].day1 -info[group[i].nodes[k]].day2;
						min_index = k;
					}
				}

				ans += info[group[i].nodes[min_index]].day1;
				for(int k = 0; k < group[i].nodes.size(); k++){
					if(k != min_index){
						ans += info[group[i].nodes[k]].day2;
					}
				}

			}else{
				for(int k = 0; k < group[i].nodes.size(); k++){
					ans += info[group[i].nodes[k]].day2;
				}
			}
		}
	}

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3556
final_rank: 19

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

int N;
int day1[1111],day2[1111];
string name[1111],sup[1111];
const int INF = 1000000007;
vector<int> G[1111];
vector<int> rG[1111];

bool used[1111];
vector<int> V[1111];
vector<int> vs;
void init(){
  for(int i=0;i<N;i++) G[i].clear();
  for(int i=0;i<N;i++) rG[i].clear();
  for(int i=0;i<N;i++) V[i].clear();  
}
int dfs(int v){
  if( used[v] ) return 0;
  int res = 0;
  used[v] = true;
  for( int to : G[v] ){
    res += dfs( to );
  }
  vs.push_back( v );
  return res + day2[v];
}
void rdfs(int v,int cnt){
  if( used[v] ) return;
  used[v] = true;
  for( int to : rG[v] ) {
    rdfs( to, cnt );
  }
  V[cnt].push_back(v);
}
int scc(){
  memset( used, 0, sizeof( used ) );
  vs.clear();
  for(int i=0;i<N;i++){
    dfs( i );
  }
  memset( used, 0, sizeof( used ) );
  reverse( vs.begin(), vs.end() );
  int cnt = 0;
  for(int v : vs ){
    if( used[v] ) continue;    
    rdfs( v, cnt++ );
  }
  return cnt;
}
void add_edge(int from,int to){
  G[from].push_back( to );
  rG[to].push_back( from );
}

int main(){
  while( cin >> N && N ){
    init();
    map<string,int> H;
    for(int i=0;i<N;i++){
      cin >> name[i] >> day1[i] >> sup[i] >> day2[i];
      H[name[i]] = i;
    }
    for(int i=0;i<N;i++)
      add_edge( H[sup[i]], H[name[i]] );

    int n = scc();
    int res = 0;
    memset( used, 0, sizeof( used ) );
    for(int i=0;i<n;i++){
      int sum = 0;
      int min_pc = INF;
      int nv = V[i].back();
      if( used[nv] ) continue;
      for( int v : V[i] ){
        sum += day2[v];
        min_pc = min( min_pc, day1[v] - day2[v] );
      }
      res += dfs(nv) + min_pc;
    }
    cout << res << endl;
  }
}
accuracy: 1
time_ms: 60
memory_kb: 3584
final_rank: 18

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1e8;
const int LMAX=2010;
class SCC{//cmp(0 - kk-1) is scc's return. Same number is group. The number is no relatoin.
	public:
	int n;
	vvi G,rG;
	vector<bool>used;
	vi vs,cmp;
	SCC(int size){
		n=size;
		G=rG=vvi(n);
		used=vector<bool>(n);
		cmp=vi(n);
		vs=vi(0);
	}
	void add_edge(int s,int t){
		G[s].pb(t);
		rG[t].pb(s);
	}
	void rdfs(int v,int k){
		used[v]=true;
		cmp[v]=k;
		rep(i,rG[v].size())if(!used[rG[v][i]])rdfs(rG[v][i],k);
	}
	void dfs(int v){
		used[v]=true;
		rep(i,G[v].size())if(!used[G[v][i]])dfs(G[v][i]);
		vs.pb(v);
	}
	int scc(){
		rep(i,n)used[i]=false;
		rep(v,n)if(!used[v])dfs(v);
		rep(i,n)used[i]=false;
		int kk=0;
		for(int i=vs.size()-1;i>=0;i--)if(!used[vs[i]])rdfs(vs[i],kk++);
		return kk;  
	}
};
vp in;
vvi G,rG;
vi visit;
int out=0;
void dfs(int a){
	out+=in[a].second;
	visit[a]=true;
	rep(i,G[a].size())if(visit[G[a][i]]==0)
		dfs(G[a][i]);
}
int main(){
	int n;
	while(cin>>n,n){
		map<string,int>m;
		vector<string>a(n),c(n);
		vi b(n),d(n);
		rep(i,n)cin>>a[i]>>b[i]>>c[i]>>d[i];
		rep(i,n)m[a[i]]=i;		
		SCC scc(n);
		rep(i,n){
			if(a[i]!=c[i])scc.add_edge(m[c[i]],m[a[i]]);
		}
		int N=scc.scc();
		in=vp(N);
		G=rG=vvi(N);
		rep(i,N){
			vi t;
			rep(j,n)if(scc.cmp[j]==i)t.pb(j);
			if(t.size()==1){
				if(i!=scc.cmp[m[c[t[0]]]]){
					rG[i].pb(scc.cmp[m[c[t[0]]]]);
					G[scc.cmp[m[c[t[0]]]]].pb(i);
				}
				in[i]=pii(b[t[0]],d[t[0]]);
			}else{
				int mi=inf,sum=0;
				rep(j,t.size())sum+=d[t[j]];
				rep(j,t.size())mi=min(mi,b[t[j]]-d[t[j]]);
				in[i]=pii(mi+sum,inf);
			}
		}
		visit=vi(N);
		out=0;
		rep(i,N)if(visit[i]==0&&rG[i].size()==0){
			out+=in[i].first-in[i].second;
			dfs(i);
		}
		cout<<out<<endl;
		
	}
}
accuracy: 1
time_ms: 150
memory_kb: 1712
final_rank: 15

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 1000;
const int INF = 1 << 30;

/* typedef */

typedef vector<int> vi;
typedef map<string,int> msi;

struct Tool {
  string name, sup;
  int day1, day2, diff, i, si;

  void print() {
    printf("Tool: %s(%d):%d, %s(%d):%d\n",
	   name.c_str(), i, day1, sup.c_str(), si, day2);
  }
};

/* global variables */

int n;
Tool tools[MAX_N];
msi nhash;

bool used[MAX_N], tmpused[MAX_N];

/* subroutines */

/* main */

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

    nhash.clear();
    for (int i = 0; i < n; i++) {
      Tool& ti = tools[i];
      cin >> ti.name >> ti.day1 >> ti.sup >> ti.day2;
      ti.diff = ti.day1 - ti.day2;
      ti.i = i;
      ti.si = -1;
      nhash[ti.name] = i;
    }
    for (int i = 0; i < n; i++) {
      Tool& ti = tools[i];
      ti.si = nhash[ti.sup];
      //ti.print();
    }

    memset(used, false, sizeof(used));

    int minsum = 0;
    
    // find loops
    for (int i = 0; i < n; i++) {
      Tool& ti = tools[i];
      if (! used[i]) {
	memset(tmpused, false, sizeof(tmpused));
	tmpused[i] = true;
	int j = ti.si;
	for (; ! tmpused[j]; j = tools[j].si) {
	  if (used[j]) break;
	  tmpused[j] = true;
	}
	if (used[j]) continue;

	int sumloop = tools[j].day2;
	int mindiff = tools[j].diff;

	used[j] = true;
	for (int k = tools[j].si; k != j; k = tools[k].si) {
	  used[k] = true;
	  sumloop += tools[k].day2;
	  if (mindiff > tools[k].diff) mindiff = tools[k].diff;
	}

	minsum += sumloop + mindiff;
      }
    }
    //cout << ln << endl;

    // check leafs
    bool changed = true;
    while (changed) {
      changed = false;

      for (int i = 0; i < n; i++) {
	Tool& ti = tools[i];
	if (! used[i] && used[ti.si]) {
	  used[i] = true;
	  minsum += ti.day2;
	  changed = true;
	}
      }
    }
    
    cout << minsum << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 1412
final_rank: 3

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

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

const int IINF = INT_MAX;

struct Edge{
  int to,cost;
  Edge(int to=IINF,int cost=IINF):to(to),cost(cost){}
};

map<string,int> mp;
int day1[1100],N,par[1100],mp_idx;
vector<Edge> G[1100];
bool used[1100];

inline int getIndex(string s){
  if( mp.find(s) == mp.end() ) return mp[s] = mp_idx++;
  return mp[s];
}

inline void init(){
  mp_idx = 0;
  mp.clear();
  rep(i,N) G[i].clear(), par[i] = i;
}

int find(int x){
  if( par[x] == x ) return par[x];
  return par[x] = find(par[x]);
}

inline void unit(int x,int y){
  x = find(x), y = find(y);
  if( x != y ) par[x] = par[y];
}

void dfs(int cur,int &cost){
  if( used[cur] ) return;
  used[cur] = true;
  rep(i,(int)G[cur].size()){
    int to = G[cur][i].to;
    if( !used[to] && par[cur] == par[to] ){
      cost += G[cur][i].cost;
      dfs(to,cost);
    }
  }
}

inline void compute(){
  set<int> S;
  rep(i,N) S.insert(find(i));
  int cnt = S.size();
  int mincost[N];
  rep(i,N) mincost[i] = IINF;
  rep(i,N){
    int idx = par[i];
    int cost = day1[i];
    rep(j,N) used[j] = false;
    dfs(i,cost);
    rep(j,N) if( !used[j] && par[j] == par[i] ) cost += day1[j];
    mincost[idx] = min(mincost[idx],cost);
  }
  int ans = 0;
  for( int i : S ) ans += mincost[i];
  cout << ans << endl;
}

int main(){
  while( cin >> N, N ){

    init();
    rep(i,N){
      string a,b;
      int c,d;
      cin >> a >> c >> b >> d;
      int ia = getIndex(a);
      day1[ia] = c;
      int ib = getIndex(b);
      if( ia == ib ) continue;
      G[ib].push_back(Edge(ia,d));
      unit(ia,ib);
    }

    compute();

  }
  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 1468
final_rank: 13

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

using namespace std;

class UnionFind{
public:
  vector<int> par, rank;

  void init(int n){
    par.resize(n);
    rank.resize(n);
    for(int i = 0; i < n; i++){
      par[i] = i;
      rank[i] = 0;
    }
  }

  int find(int x){
    if(par[x] == x) return x;
    else return par[x] = find(par[x]);
  }
  
  void unite(int x, int y){
    x = find(x);
    y = find(y);
    if(x == y) return;
    if(rank[x] < rank[y]) par[x] = par[y];
    else{
      par[y] = par[x];
      if(rank[x] == rank[y]) rank[x]++;
    }
  }
};

typedef pair<int, int> P; // to, cost
const int MAX = 1005;
map<string, int> M;
UnionFind uf;
int cost[MAX],n;
vector<P> E[MAX];
bool used[MAX];

int get_index(const string& s){
  if(M.count(s)) return M[s];
  else return M[s] = M.size()-1;
}

void init(){
  uf.init(n);
  M.clear();
  for(int i = 0; i < MAX; i++) E[i].clear();
}

void input(){
  for(int i = 0; i < n; i++){
    string a,b;
    int c,d;
    cin >> a >> c >> b >> d;
    cost[get_index(a)] = c;
    get_index(b);
    if(a == b) continue;
    E[get_index(b)].push_back(P(get_index(a), d));
    //    cout << b << " -> " << a << endl;
    uf.unite(get_index(a), get_index(b));
  }
}

void dfs(int pos, P& p){ // vertex cost
  
  if(used[pos]) return;
  used[pos] = true;
  p.first++;

  for(int i = 0; i < (int)E[pos].size(); i++){
    if(!used[E[pos][i].first]){
      dfs(E[pos][i].first, p);
      p.second += E[pos][i].second;
    }
  }
}

void solve(){
  vector<int> v[MAX];
  for(int i = 0; i < n; i++) v[uf.find(i)].push_back(i);
 
  int ans = 0;

  for(int i = 0; i < MAX; i++){
    if(v[i].size() == 0) continue;
    int tmp = -1;
    for(int j = 0; j < (int)v[i].size(); j++){
      memset(used, false, sizeof(used));
      P p = P(0,0);
      dfs(v[i][j],p);
      p.second += cost[v[i][j]];
/*******      if(v[i][j] == 0){
        cout << p.first << " " << p.second << endl;
        }*/
      if((p.first == (int)v[i].size()) && (tmp == -1 || tmp > p.second)) tmp = p.second;
    }
    ans += tmp;
  }
  cout << ans << endl;
}

int main(){
  
  while(cin >> n && n){
    init();
    input();
    solve();
  }
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 1512
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)

using namespace std;
int main(){
    int n;
    while(cin >> n && n){
        vector<string> name(n), sup(n);
        vector<int> high(n), low(n);
        REP(i, n) cin >> name[i] >> high[i] >> sup[i] >> low[i];
        map<string, int> index;
        REP(i, n) index[ name[i] ] = i;
        vector<int> color(n, 0);
        int ans = 0;
        REP(i, n) if(color[i] == 0){
            vector<int> list;
            int u = i;
            while(color[u] == 0){
                list.push_back(u);
                color[u] = 1;
                u = index[ sup[u] ];
            }
            if(color[u] == 1){
                int min_sum = INT_MAX;
                bool in_roop = false;
                for(int h : list){
                    if(h == u) in_roop = true;
                    if(!in_roop) continue;
                    int sum = 0;
                    for(int li : list){
                        sum += (li == h ? high[li] : low[li]);
                    }
                    if(min_sum > sum) min_sum = sum;
                }
                ans += min_sum;
            }else if(color[u] == 2){
                for(int li : list){
                    ans += low[li];
                }
            }
            for(int li : list){
                color[li] = 2;
            }
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 1432
final_rank: 4

code_snippet: //55
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<deque>

using namespace std;

int n;
string na[1000],su[1000];
int d[1000],dd[1000];
map<string,int> m;
vector<int> ds[1000];
bool p[1000];
int cut[1000];

int dfs(int x){
  if(p[x])return 0;
  int s=p[m[su[x]]]?d[x]-dd[x]:0;
  p[x]=true;
  for(int i=0;i<ds[x].size();i++){
    s+=dfs(ds[x][i]);
  }
  return s;
}

bool cmp(int a,int b){
  return cut[a]>cut[b];
}

int main(){
  while(cin>>n,n){
    m.clear();
    for(int i=0;i<n;i++){
      cin>>na[i]>>d[i]>>su[i]>>dd[i];
      m[na[i]]=i;
    }
    for(int i=0;i<n;i++){
      ds[i].clear();
    }
    for(int i=0;i<n;i++){
      ds[m[su[i]]].push_back(m[na[i]]);
    }
    for(int i=0;i<1000;i++){
      fill(p,p+n,false);
      cut[i]=dfs(i);
    }
    deque<int> ef(n);
    for(int i=0;i<n;i++){
      ef[i]=i;
    }
    sort(ef.begin(),ef.end(),cmp);
    bool done[1000]={};
    int a=0;
    for(int i=0;i<n;i++){
      for(int nt=0;nt<n;nt++){
	if(!done[nt]){
	  if(done[m[su[nt]]]){
	    a+=dd[nt];
	    done[nt]=true;
	    goto next;
	  }
	}
      }
      while(done[ef[0]]){
	ef.pop_front();
      }
      a+=d[ef[0]];
      done[ef[0]]=true;
    next:
      ;
    }
    cout<<a<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 1540
memory_kb: 1604
final_rank: 20

code_snippet: #include <iostream>
#include <vector>
#include <map>
#include <climits>
#include <cstring>
using namespace std;

typedef pair<int,int> P;

int n, ans;
int t[1002];
vector<P> g[1002];
map<string,int> name;
bool used[1002], loop[1002];

int getId(string s){
  if(name.find(s) != name.end()){
    return name[s];
  }
  int size = name.size();
  return name[s] = size;
}

void solve(){
  memset(used, 0, sizeof(used));

  for(int i = 0; i < n; i++){
    if(used[i]) continue;

    memset(loop, 0, sizeof(loop));

    int id = i;
    bool flg = true;

    while(!loop[id]){
      if(used[id]){
	flg = false;
	break;
      }

      loop[id] = true;
      used[id] = true;
      id = g[id][0].first;
    }
    if(!flg) continue;

    int start = id;
    int minId = start;

    id = g[start][0].first;

    while(id != start){
      if(t[minId] - g[minId][0].second > t[id] - g[id][0].second){
	minId = id;
      }
      id = g[id][0].first;
    }

    ans += t[minId] - g[minId][0].second;
  }

  cout << ans << endl;
}

int main(){
  while(cin >> n, n){
    ans = 0;
    name.clear();

    for(int i = 0; i < 1002; i++){
      g[i].clear();
    }

    for(int i = 0; i < n; i++){
      string FROM, TO;
      int a, b;
      cin >> FROM >> a >> TO >> b;

      int from = getId(FROM);
      int to = getId(TO);
      t[from] = a;
      g[from].push_back(P(to, b));
      ans += b;
    }

    solve();
  }
}
accuracy: 1
time_ms: 90
memory_kb: 1388
final_rank: 5

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <map>

#define rep(i,n) for(int i=0; i<(n); i++)

using namespace std;

typedef vector<vector<int> > graph;

void getReversedGraph(graph& G, graph* rG) {
    *rG = graph(G.size());
    for (int i = 0; i < (int)G.size(); i++) {
        for (int j = 0; j < (int)G[i].size(); j++) {
            (*rG)[G[i][j]].push_back(i);
        }
    }
}

void getSCCGraph(graph& G, graph* SCCGraph, vector<int>* table) {
    const int V = G.size();
    graph rG;
    vector<vector<int> > SCCList;
    vector<int> postOrder;
    bool *used = new bool[V];
    int *nextIndex = new int[V];
    *table = vector<int>(V);
    getReversedGraph(G, &rG);

    // DFS
    for (int i = 0; i < V; i++) {
        used[i] = false;
        nextIndex[i] = 0;
    }

    for (int i = 0; i < V; i++) {
        if (used[i]) {
            continue;
        }
        used[i] = true;
        stack<int> st;
        st.push(i);
        while (!st.empty()) {
            int v = st.top();
            if (nextIndex[v] == (int)G[v].size()) {
                postOrder.push_back(v);
                st.pop();
            } else {
                int newv = G[v][nextIndex[v]];
                if (!used[newv]) {
                    st.push(newv);
                    used[newv] = true;
                }
                nextIndex[v]++;
            }
        }
    }
    // Reversed DFS
    for (int i = 0; i < V; i++) {
        used[i] = false;
        nextIndex[i] = 0;
    }

    int it = 0;
    for (int i = V - 1; i >= 0; i--) {
        int index = postOrder[i];
        if (used[index]) {
            continue;
        }
        used[index] = true;
        (*table)[index] = it;
        stack<int> st;
        vector<int> list;
        st.push(index);
        list.push_back(index);
        while (!st.empty()) {
            int v = st.top();
            if (nextIndex[v] == (int)rG[v].size()) {
                st.pop();
            } else {
                int newv = rG[v][nextIndex[v]];
                if (!used[newv]) {
                    st.push(newv);
                    list.push_back(newv);
                    used[newv] = true;
                    (*table)[newv] = it;
                }
                nextIndex[v]++;
            }
        }
        SCCList.push_back(list);
        it++;
    }

    // create new graph;
    const int compressedV = it;
    *SCCGraph = graph(compressedV);
 
    for (int i = 0; i < compressedV; i++) {
        map<int, bool> edgeUsed;
        for (int j = 0; j < (int)SCCList[i].size(); j++) {
            int v = SCCList[i][j];
            for (int k = 0; k < (int)G[v].size(); k++) {
                int w = G[v][k];
                // v -> w
                if (!edgeUsed[(*table)[w]]) {
                    edgeUsed[(*table)[w]] = true;
                    if (i != (*table)[w]) (*SCCGraph)[i].push_back((*table)[w]);
                }
            }
        }
    }

    delete[] used;
    delete[] nextIndex;
}

bool used[2005];

void check(int v, graph& G, bool* used) {
    if (used[v])return;
    used[v] = true;
    rep(i, G[v].size()) {
        check(G[v][i], G, used);
    }
}

int solve(int n) {
    string s1,s2;
    int d1,d2;
    graph G(n), sccG, rG;
    vector<int> table;
    map<string, int> toId;
    map<int, int> plus;
    int ans = 0;
    int id = 0;
    rep(i,n) {
        cin >> s1 >> d1 >> s2 >> d2;
        if (toId.find(s1) == toId.end()) {
            toId[s1] = id;
            id++;
        }
        if (toId.find(s2) == toId.end()) {
            toId[s2] = id;
            id++;
        }
        ans+= d2;
        if (s1 != s2)G[toId[s2]].push_back(toId[s1]);
        plus[toId[s1]] = d1 - d2;
    }
    
    getSCCGraph(G, &sccG, &table);
    rep(i, 2005)used[i] = false;
    rep(i, sccG.size()) {
        vector<int> p;
        if (used[i])continue;
        //cerr << i << endl;
        //cerr << "\t";
        rep(j, table.size()) {
            if (table[j] == i) {
                p.push_back(plus[j]);
                //cerr << j << ":" << p[j] << " ";
            }
        }
        //cerr << endl;
        sort(p.begin(), p.end());
        ans += p[0];
        check(i, sccG, used);
    }
    return ans;
}

int main() {
    int n;
    while(cin >> n, n) {
        cout << solve(n) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 1584
final_rank: 12

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<string> s1(n), s2(n);
        vector<int> t1(n), t2(n);
        map<string, int> index;
        for(int i=0; i<n; ++i){
            cin >> s1[i] >> t1[i] >> s2[i] >> t2[i];
            index[s1[i]] = i;
        }

        vector<int> sup(n);
        vector<vector<int> > edges(n);
        for(int i=0; i<n; ++i){
            sup[i] = index[s2[i]];
            if(s1[i] != s2[i])
                edges[index[s2[i]]].push_back(i);
        }

        int ret = 0;
        vector<bool> make(n, false);
        for(int i=0; i<n; ++i){
            if(make[i])
                continue;

            int j = i;
            vector<bool> check(n, false);
            while(!check[j]){
                check[j] = true;
                j = sup[j];
            }

            check.assign(n, false);
            int k = j;
            while(!check[j]){
                if(t1[j] - t2[j] < t1[k] - t2[k])
                    k = j;
                check[j] = true;
                j = sup[j];
            }

            ret += t1[k] - t2[k];
            queue<int> q;
            q.push(k);
            while(!q.empty()){
                int a = q.front();
                q.pop();
                ret += t2[a];
                make[a] = true;

                for(unsigned l=0; l<edges[a].size(); ++l){
                    int b = edges[a][l];
                    if(!make[b])
                        q.push(b);
                }
            }
        }

        cout << ret << endl;
    }
}
accuracy: 1
time_ms: 90
memory_kb: 1488
final_rank: 7

code_snippet: //include
//------------------------------------------
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>

using namespace std;

//conversion
//------------------------------------------
inline int toInt(string s) {int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string toStr(T x) {ostringstream sout; sout << x; return sout.str();}

//math
//-------------------------------------------
template<class T> inline T sqr(T x) {return x*x;}

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

//container util
//------------------------------------------
#define ALL(a, n)  (a), (a) + (n)
#define VALL(v)  (v).begin(),(v).end()
#define VADD(v, e) (v).push_back(e)
#define SADD(s, e) (s).insert(e)
#define STADD(s, e) (s).push(e)
#define QADD(q, e) (q).push(e)
#define PQADD(q, e) (q).push(e)
#define STPOP(s, e) typeof((q).top()) e = (q).top(); (q).pop()
#define QPOP(q) typeof((q).front()) e = (q).front(); (q).pop()
#define PQPOP(q) typeof((q).top()) e = (q).top(); (q).pop()
#define MP make_pair
#define PF(p) (p).first
#define PS(p) (p).second
#define SZ(a) int((a).size())
#define EACH(i, c) for(typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(a, n) sort(ALL(a, n))
#define VSORT(c) sort(VALL(c))
#define RSORT(a, n) sort(ALL(a, n), greater<typeof(a[0])>())
#define VRSORT(v) sort(VALL(v), greater<typeof(v[0])>())
#define INDEX(a, n, x) find(ALL(a, n), x) - a
#define VINDEX(v, x) find(VALL(v), x) - v.begin()
#define BOUND(a, n, x) lower_bound(ALL(a, n), x) - a
#define VBOUND(v, x) lower_bound(VALL(v), x) - v.begin()

//repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a);i < (b); ++i)
#define RFOR(i, a, b) for (int i = (b) - 1; i >= (a); --i)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)

//IO
//------------------------------------------
#define LF(x) cout << (x) << endl;
#define LF2(x, y) cout << (x) << " " << (y) << endl;
#define LFA(a, n) cout << a[0]; FOR(i, 1, n) {cout << " " << a[i];} cout << endl;
#define LFD(x, w) cout.width = (w); cout << (x) << endl;
#define LFDA(a, n, w) REP(i, n) cout.width = (w); cout << a[i] << endl;
#define LFP(x, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << (x) << endl;
#define LFP2(x, y, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << (x) << " " << (y) << endl;
#define LFPA(a, n, w) cout << setprecision((w)); cout << setiosflags(ios::fixed); cout << a[0]; FOR(i, 1, n) {cout << " " << a[i];} cout << endl;

//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);
const int INF = 1e9;

//clear memory
//--------------------------------------------
#define CLR(a) memset((a), 0 , sizeof(a))

//debug
//--------------------------------------------
#define DUMP(x)  cerr << #x << " = " << (x) << endl;
#define DEBUG(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl;
#define DUMPA(a, n) cerr << #a << " = {" << a[0]; FOR(i, 1, n) { cout << ", " << a[i]; } cerr << "}" << endl;
#define DEBUGA(a, n) cerr << #a << " = {" << a[0]; FOR(i, 1, n) { cout << ", " << a[i]; } cerr << "} (L" << __LINE__ << ")" << endl;
#define DUMPAA(a, n, m) REP(i, n) {REP(j, m) {cout << a[i][j] << " ";} cout << endl;}
#define DEBUGAA(a, n, m) DUMPAA(a, n, m) cout << "(L" << __LINE__ << ")" << endl;

//#include <uft>
class uft
{
public:
	int N;
	int n;
	int* p;
	int* r;
	
	uft(const int N)
	{
		this->N = N;
		p = new int[N];
		r = new int[N];
	}
	
	~uft()
	{
		delete[] p;
		delete[] r;
	}
	
	void init(int n)
	{
		this->n = n;
		for (int i = 0; i < n; i++) {
			p[i] = i;
			r[i] = 0;
		}
	}
	
	int find(int x)
	{
		if (p[x] == x) {
			return x;
		}
		p[x] = find(p[x]);
		return p[x];
	}
	
	void unite(int x, int y)
	{
		int a = find(x);
		int b = find(y);
		if (a == b) {
			return;
		}
		if(r[a] < r[b]) {
			p[a] = b;
		}
		else if (r[a] == r[b]){
			p[a] = b;
			r[b]++;
		}
		else {
			p[b] = a;
		}
	}
	
	bool same(int x, int y)
	{
		return find(x) == find(y);
	}

};

//#include_end <uft>

const int N = 1000;
int n;
string name[N];
int day1[N];
string sup[N];
int day2[N];
map<string, int> f;
uft uft(N);
VI e[N];
int m[N];
int dp[N];
bool v[N];

int dfs(int k)
{
	v[k] = true;
	int ans = day1[k];
	REP(i, e[k].size()) {
		if(!v[e[k][i]]) ans += dfs(e[k][i]) - day1[e[k][i]] + day2[e[k][i]];
	}
	return ans;
}

void init()
{
}

void solve()
{
	f.clear();
	REP(i, n) {
		f[name[i]] = i;
		e[i].clear();
	}
	uft.init(n);
	fill(ALL(m, n), 1);
	REP(i, n) {
		int t = f[name[i]];
		int u = f[sup[i]];
		if (!uft.same(t, u)) {
			uft.unite(t, u);
			m[t] += m[u];
			REP(j, n) {
				if (uft.same(t, j)) {
					m[j] = m[t];
				}
			}
		}
		VADD(e[u], t);
	}
	fill(ALL(dp, n), INF);
	REP(i, n) {
		fill(ALL(v, n), false);
		int x = dfs(i);
		int y = 0;
		REP(j, n) {
			if (v[j]) ++y;
		}
		if (y < m[i]) continue;
		REP(j, n) {
			if (uft.same(i, j)) {
				dp[j] = min(dp[j], x);
			}
		}
	}
	int ans = 0;
	REP(i, n) {
		bool b = false;
		REP(j, i) {
			b |= uft.same(i, j);
		}
		if (!b) ans += dp[i];
	}
	LF(ans);
}

int main()
{
	init();
	while (cin >> n, n) {
		REP(i, n) cin >> name[i] >> day1[i] >> sup[i] >> day2[i];
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 790
memory_kb: 0
final_rank: 10

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <cstring>

using namespace std;

typedef pair<int,int> pii;

bool used[1001];
int n;
vector<int> G[1001];
pii costs[1001];
int idx=0;
map<string,int> indices;
int nxt[1001];
int in[1001];
int sumCosts=0;
bool used2[1001];

// üü0Ìm[hÉÂ¢ÄTõ(ÂHÍ¶Ýµ¦È¢)
void search1(int s){
	used[s]=true;
	for(int i=0;i<(int)G[s].size();i++){
		int to=G[s][i];
		if(!used[to]){
			nxt[s]=to;
			sumCosts+=costs[to].second;
			search1(to);
		}
	}
}
// ü_ª ém[h©çTõðnßé
void search2(int s){
	used[s]=true;
	used2[s]=true;
	for(int i=0;i<(int)G[s].size();i++){
		int to=G[s][i];
		if(!used[to]){
			nxt[s]=to;
			sumCosts+=costs[to].second;
			search2(to);
		}
		// ÂHð­©µ½êAÂHÌÅÅàRXg·Ì¬³¢àÌðÌp
		else{
			// ¡ñÊßµ½êÅÍÈ¢ê
			if(!used2[to])continue;
			vector<pii> v;
			int cur=to;
			while(1){
				v.push_back(pii(costs[cur].first-costs[cur].second,cur));
				if(cur==s)break;
				int tto=nxt[cur];
				cur=tto;
			}
			sort(v.begin(),v.end());
			sumCosts+=costs[v[0].second].first;
			sumCosts-=costs[v[0].second].second;
		}
	}
}

int main(){

	while(cin>>n&&n){
		sumCosts=0;
		memset(in,0,sizeof(in));
		memset(used,0,sizeof(used));
		indices.clear();
		idx=0;
		for(int i=0;i<1001;i++)G[i].clear();
		for(int i=0;i<n;i++){
			string a,b;
			int c,d;
			cin>>a>>c>>b>>d;
			if(indices.find(a)==indices.end())indices[a]=idx++;
			if(indices.find(b)==indices.end())indices[b]=idx++;
			if(a!=b){
				G[indices[b]].push_back(indices[a]);
				in[indices[a]]++;
			}
			costs[indices[a]]=pii(c,d);
		}
		// ü_ª³¢¨ðTõ
		for(int i=0;i<idx;i++){
			if(in[i]==0&&!used[i]){
				// ÅÌvfÍK¸æé
				sumCosts+=costs[i].first;
				search1(i);
			}
		}
		// Ü¾TõµÄ¢È¢àÌð·×ÄTõ
		for(int i=0;i<idx;i++){
			if(!used[i]){
				memset(used2,0,sizeof(used2));
				sumCosts+=costs[i].second;
				search2(i);
			}
		}
		cout<<sumCosts<<endl;
	}

	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 1140
final_rank: 6

code_snippet: #include<map>
#include<string>
#include<vector>
#include<iostream>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

typedef vector< vector<int> > vvi;

const int INF=1<<29;

void GabowDFS(int u,vector<bool> &visited,vector<int> &nodes,const vvi &adj){
	if(visited[u]) return;
	visited[u]=true;
	rep(i,adj[u].size()){
		int v=adj[u][i];
		if(!visited[v]) GabowDFS(v,visited,nodes,adj);
	}
	nodes.push_back(u);
}

vvi GabowSCC(const vvi &adj){
	int n=adj.size();
	vector<int> ord;
	vector<bool> visited(n);
	rep(u,n) GabowDFS(u,visited,ord,adj);

	vvi radj(n);
	rep(u,n) rep(i,adj[u].size()) radj[adj[u][i]].push_back(u);

	vvi sccs;
	rep(u,n) visited[u]=false;
	for(int i=n-1;i>=0;i--){
		int u=ord[i];
		vector<int> scc;
		GabowDFS(u,visited,scc,radj);
		if(scc.size()>0) sccs.push_back(scc);
	}
	return sccs;
}

int main(){
	for(int n;cin>>n,n;){
		int m=0;
		map<string,int> f;

		vvi adj(n);
		int day1[1000],day2[1000];
		rep(i,n){
			string s1,s2;
			int d1,d2; cin>>s1>>d1>>s2>>d2;
			if(f.count(s1)==0) f[s1]=m++;
			if(f.count(s2)==0) f[s2]=m++;

			int u=f[s2],v=f[s1];
			adj[u].push_back(v);
			day1[v]=d1;
			day2[v]=d2;
		}

		vvi scc=GabowSCC(adj);

		int ans=0;
		bool tool[1000]={};
		rep(i,scc.size()){
			int dif=INF;
			bool start=true;
			rep(j,scc[i].size()){
				int u=scc[i][j];
				ans+=day2[u];
				dif=min(dif,day1[u]-day2[u]);
				if(tool[u]) start=false;
			}
			if(start) ans+=dif;

			rep(j,scc[i].size()){
				int u=scc[i][j];
				rep(k,adj[u].size()) tool[adj[u][k]]=true;
			}
		}

		printf("%d\n",ans);
	}

	return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 0
final_rank: 1

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

typedef vector<vector<int> > graph;

#define REP(i,n) for(int i=0; i<n; i++)


void visit(graph& g, vector<int>& PostOrder, vector<bool>& visited, int ps)
{
	visited[ps]=1;
	int S=g[ps].size();
	REP(i,S)
	{
		int next=g[ps][i];
		if(visited[next]) continue;
		visit(g, PostOrder, visited, next);
	}
	
	PostOrder.push_back(ps);
}

void walk(graph& g, vector<int>& in, int ps, int gcnt)
{
	in[ps]=gcnt;
	
	int S=g[ps].size();
	REP(i,S)
	{
		int next=g[ps][i];
		if(in[next]!=-1) continue;
		walk(g,in,next,gcnt);
	}
}

//StronglyConnectedComponent
int SCC(vector<int>& in, int V, graph& g, graph& rg)
{
	int gcnt=0;
	vector<int> PostOrder;
	vector<bool> visited(V,false);
	
	REP(i,V)
	{
		if(visited[i]) continue;
		visit(g,PostOrder,visited, i);
	}
		
	for(int i=PostOrder.size()-1; i>=0; --i)
	{
		if(in[PostOrder[i]]==-1) 
		{
			walk(rg,in,PostOrder[i],gcnt++);
		}
	}

	return gcnt;
}

int recipe[1050], self[1050],reduce[1050];

int dfs(int p, vector<bool>& use, graph& g, graph& c)
{
	use[p]=1;

	int ret=0;
	for(int i=0; i<g[p].size(); i++)
	{
		int next=g[p][i];
		if(use[next]) continue;
		ret+=dfs(next, use, g, c);
		ret+=c[p][i];
	}

	return ret;

}

int calc(vector<int>& v, vector<bool>& created, graph& g, graph& c)
{
	vector<bool> use(10000, 1);
	for(int i=0; i<v.size(); i++)
		use[v[i]]=0;

	int ret=0,mn=(1<<24),r;
	if(v.size()==1)
	{
		int p=v[0];
		if(created[recipe[p]]) ret=reduce[p];
		else ret=self[p];
	}
	else
	{
		for(int i=0; i<v.size(); i++)
		{
			int p=v[i];
			if(self[p]-reduce[p]<mn)
			{
				r=p;
				mn=self[p]-reduce[p];
			}
		}

		for(int i=0; i<v.size(); i++)
		{
			int p=v[i];
			if(p==r) ret+=self[p];
			else ret+=reduce[p];
		}
	}

	for(int i=0; i<v.size(); i++)
		created[v[i]]=1;

	return ret;
}

int main()
{
	int N;
	while(cin >> N, N)
	{
		graph g(N), rg(N), c(N), rc(N);

		int dcnt=0;
		map<string, int> dic;
		for(int i=0; i<N; i++)
		{
			string s,t;
			int a,b,u,v;
			cin >> s >> a >> t >> b;

			if(!dic.count(s)) dic[s]=dcnt++;
			if(!dic.count(t)) dic[t]=dcnt++;
			
			u=dic[s];
			v=dic[t];

			 g[u].push_back(v);
			rg[v].push_back(u);
			 c[u].push_back(b);
			rc[v].push_back(b);

			self[u]=a;
			recipe[u]=v;
			reduce[u]=b;
		}

		vector<int> in(N, -1);
		int gcnt=SCC(in,N,rg,g);

		vector<vector<int> > loop(gcnt);
		for(int i=0; i<N; i++)
			loop[in[i]].push_back(i);

		vector<bool> created(N, 0);

		int ans=0;
		for(int i=0; i<gcnt; i++)
		{
			ans+=calc(loop[i], created, rg, rc);
		}

		printf("%d\n", ans);
	}
}
accuracy: 1
time_ms: 260
memory_kb: 1188
final_rank: 9

code_snippet: #include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

typedef vector<vector<int> > graph;

#define REP(i,n) for(int i=0; i<n; i++)


void visit(graph& g, vector<int>& PostOrder, vector<bool>& visited, int ps)
{
	visited[ps]=1;
	int S=g[ps].size();
	REP(i,S)
	{
		int next=g[ps][i];
		if(visited[next]) continue;
		visit(g, PostOrder, visited, next);
	}
	
	PostOrder.push_back(ps);
}

void walk(graph& g, vector<int>& in, int ps, int gcnt)
{
	in[ps]=gcnt;
	
	int S=g[ps].size();
	REP(i,S)
	{
		int next=g[ps][i];
		if(in[next]!=-1) continue;
		walk(g,in,next,gcnt);
	}
}

//StronglyConnectedComponent
int SCC(vector<int>& in, int V, graph& g, graph& rg)
{
	int gcnt=0;
	vector<int> PostOrder;
	vector<bool> visited(V,false);
	
	REP(i,V)
	{
		if(visited[i]) continue;
		visit(g,PostOrder,visited, i);
	}
		
	for(int i=PostOrder.size()-1; i>=0; --i)
	{
		if(in[PostOrder[i]]==-1) 
		{
			walk(rg,in,PostOrder[i],gcnt++);
		}
	}

	return gcnt;
}

int recipe[1050], self[1050],reduce[1050];

int dfs(int p, vector<bool>& use, graph& g, graph& c)
{
	use[p]=1;

	int ret=0;
	for(int i=0; i<g[p].size(); i++)
	{
		int next=g[p][i];
		if(use[next]) continue;
		ret+=dfs(next, use, g, c);
		ret+=c[p][i];
	}

	return ret;

}

int calc(vector<int>& v, vector<bool>& created, graph& g, graph& c)
{
	vector<bool> use(10000, 1);
	for(int i=0; i<v.size(); i++)
		use[v[i]]=0;

	int ret=(1<<24);
	for(int i=0; i<v.size(); i++)
	{
		vector<bool> u(use);
		int p=v[i], t=dfs(p,u,g,c);
		if(created[recipe[p]])  t+=reduce[p];
		else					t+=self[p];
		
		ret=min(ret, t);
	}

	for(int i=0; i<v.size(); i++)
		created[v[i]]=1;

	return ret;
}

int main()
{
	int N;
	while(cin >> N, N)
	{
		graph g(N), rg(N), c(N), rc(N);

		int dcnt=0;
		map<string, int> dic;
		for(int i=0; i<N; i++)
		{
			string s,t;
			int a,b,u,v;
			cin >> s >> a >> t >> b;

			if(!dic.count(s)) dic[s]=dcnt++;
			if(!dic.count(t)) dic[t]=dcnt++;
			
			u=dic[s];
			v=dic[t];

			 g[u].push_back(v);
			rg[v].push_back(u);
			 c[u].push_back(b);
			rc[v].push_back(b);

			self[u]=a;
			recipe[u]=v;
			reduce[u]=b;
		}

		vector<int> in(N, -1);
		int gcnt=SCC(in,N,rg,g);

		vector<vector<int> > loop(gcnt);
		for(int i=0; i<N; i++)
			loop[in[i]].push_back(i);

		vector<bool> created(N, 0);

		int ans=0;
		for(int i=0; i<gcnt; i++)
		{
			ans+=calc(loop[i], created, rg, rc);
		}

		printf("%d\n", ans);
	}
}

/*
4
gu 20 pa 10
ci 20 gu 10
pa 20 ci 10
hoge 20 pa 10
*/
accuracy: 1
time_ms: 330
memory_kb: 1188
final_rank: 14

code_snippet: #include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <map>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1<<29;

int n;
vector<int> v[1000];
map<string, int> id;
string s[1000], t[1000];
int d1[1000], d2[1000];

bool visited[1000];
int rec(int now) {
  if (visited[now]) return 0;
  visited[now] = 1;
  int res = 0;
  FOR(it, v[now]) {
    if (visited[*it]) continue;
    res += d1[*it]-d2[*it];
    res += rec(*it);
  }
  return res;
}

int dfs(int now) {
  if (visited[now]) return 0;
  visited[now] = 1;
  int res = 0;
  FOR(it, v[now]) {
    if (visited[*it]) continue;
    res += d2[*it];
    res += dfs(*it);
  }
  return res;
  
}

int main() {
  while(cin >> n, n) {
    id.clear();
    REP(i,n) {
      cin >> s[i] >> d1[i] >> t[i] >> d2[i];
      id[s[i]] = i;
    }
    REP(i,1000)
      v[i].clear();
    REP(i, n) {
      v[id[t[i]]].push_back(i);
    }
    typedef pair<int,int> pii;
    vector<pii> vv;
    REP(i,n) {
      memset(visited,0,sizeof(visited));
      int tmp = rec(i);
      vv.push_back(pii(tmp, i));
    }
    sort(ALL(vv), greater<pii>());
    memset(visited,0,sizeof(visited));
    int res = 0;
    REP(i,n) {
      int c = vv[i].second;
      if (!visited[c]) {
        res += d1[c] + dfs(c);
      }
    }
    cout << res << endl;
  }       
}
accuracy: 1
time_ms: 190
memory_kb: 1112
final_rank: 2

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;

struct tool {
    string name,sh;
    int ntime,stime;
    vector<int> edge;
    tool(string name,string sn,int ntime,int stime)
        : name(name), sh(sn), ntime(ntime), stime(stime) {edge.clear();}
};

bool seen[1001];

int dfs(vector<tool> &tv,int v) {
    seen[v] = true;
    int ret = 0;
    for(int i=0; i<tv[v].edge.size(); ++i) {
        if(seen[tv[v].edge[i]]) continue;
        ret += (tv[tv[v].edge[i]].ntime - tv[tv[v].edge[i]].stime);
        ret += dfs(tv,tv[v].edge[i]);
    }
    return ret;
}

void dfs2(vector<tool> &tv,int v) {
    seen[v] = true;
    for(int i=0; i<tv[v].edge.size(); ++i) {
        if(seen[tv[v].edge[i]]) continue;
        dfs2(tv,tv[v].edge[i]);
    }
}

int main() {
    int n;
    string s1,s2;
    int k1,k2;
    while(cin>>n, n) {
        map<string,int> idx;
        vector<tool> tv;

        int ans = 0;
        for(int i=0; i<n; ++i) {
            cin>>s1>>k1>>s2>>k2;
            idx[s1] = i;
            tv.push_back(tool(s1,s2,k1,k2));
            ans += k1;
        }

        for(int i=0; i<n; ++i) {
            if(idx.find(tv[i].sh) == idx.end()) continue;
            int id = idx[tv[i].sh];
            tv[id].edge.push_back(i);
        }

        vector<int> p(n,-1);
        for(int i=0; i<n; ++i) {
            memset(seen, false, sizeof(seen));
            p[i] = dfs(tv,i);
        }

        vector<pair<int,int> > ppv(n);
        for(int i=0; i<n; ++i) {
            ppv.push_back(make_pair(p[i],i));
        }
        sort(ppv.begin(), ppv.end());
        reverse(ppv.begin(), ppv.end());

        memset(seen, false, sizeof(seen));
        for(int i=0; i<ppv.size(); ++i) {
            int v = ppv[i].second;
            if(seen[v]) continue;
            ans -= ppv[i].first;
            dfs2(tv,v);
        }
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 270
memory_kb: 1124
final_rank: 8