Problem:
You are a programmer who loves pretty girl games (a sub-genre of dating simulation games). A game, which is titled "Floatable Heart" and was released last Friday, has arrived at your home just now. This game has multiple stories. When you complete all of those stories, you can get a special figure of the main heroine, Megumi. So, you want to hurry to play the game! But, let's calm down a bit and think how to complete all of the stories in the shortest time first.
In fact, you have the special skill that allows you to know the structure of branching points of games. By using the skill, you have found out that there are
n
branching points in this game and
i
-th branching point has
k_{i}
choices. This game is so complicated that multiple routes get to
i
-th branching point probably. You also noticed that it takes
c_{ij}
minutes to proceed from
i
-th branching point to another branching point (or an ending), if you select
j
-th choice of
i
-th branching point. Of course you need to select all the choices on all the branching points and read stories between a branching point and another branching point (or an ending) to complete all of those stories. In addition, you can assume it only takes negligible time to return to the beginning of the game ("reset") and to play from the beginning to the first branching point.
The game's manual says that this game has an additional feature called "Quick Save", and the feature allows you to record the point where you are currently playing and return there at any time later. However, this feature is not working for some bug. Thus you have to restart from the first branching point every time, if you reach an ending or quit the game on the way. Any patch to fix this bug has not been yet published. This is an imposed tribulation for the fastest players.
Well, let's estimate how long it will take for completing all of the stories in the shortest time.
Input
A data set is given in the following format.
n
k_{1}
t_{11}
c_{12}
...
t_{1k_{1}}
c_{1k_{1}}
:
:
k_{n}
t_{n1}
c_{n2}
...
t_{nk_{n}}
c_{nk_{n}}
The first line of the data set contains one integer
n
(
2 \leq n \leq 1{,}000
), which denotes the number of the branching points in this game. The following
n
lines describe the branching points. The
i
-th line describes the branching point of ID number
i
. The first integer
k_{i}
(
0 \leq k_{i} \leq 50
) is the number of choices at the
i
-th branching point.
k_{i} ≥ 0
means that the
i
-th branching point is an ending. Next
2k_{i}
integers
t_{ij}
(
1 \leq t_{ij} \leq n
) and
c_{ij}
(
0 \leq c_{ij} \leq 300
) are the information of choices.
t_{ij}
denotes the ID numbers of the next branching points when you select the
j
-th choice.
c_{ij}
denotes the time to read the story between the
i
-th branching point and the
t_{ij}
-th branching point. The branching point with ID 1 is the first branching point. You may assume all the branching point and endings are reachable from the first branching point. You may also assume that there
...(truncated)

Submitted solutions:

code_snippet: // AOJ #2627 Multi Path Story
// 2025.3.26

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int INF = 1e9;

template<typename Flow, typename Cost>
struct MinCostFlow {
    struct Edge {
        int to, rev;
        Flow cap;
        Cost cost;
    };
    int n;
    vector<vector<Edge>> g;
    vector<Cost> pot, dist;
    vector<int> prev_v, prev_e;
    const Cost INF_COST;

    MinCostFlow(int n) : n(n), g(n), INF_COST((Cost)1LL << 60) {
        pot.assign(n, 0);
        dist.assign(n, INF_COST);
        prev_v.assign(n, -1);
        prev_e.assign(n, -1);
    }

    void add_edge(int s, int t, Flow cap, Cost cost) {
        g[s].push_back({t, (int)g[t].size(), cap, cost});
        g[t].push_back({s, (int)g[s].size()-1, 0, -cost});
    }

    pair<Flow, Cost> flow(int s, int t, Flow f = numeric_limits<Flow>::max()) {
        Flow fl = 0;
        Cost cost = 0;
        while (f > 0) {
            fill(dist.begin(), dist.end(), INF_COST);
            dist[s] = 0;
            using P = pair<Cost, int>;
            priority_queue<P, vector<P>, greater<P>> pq;
            pq.push({0, s});
            while (!pq.empty()) {
                auto [d, v] = pq.top();
                pq.pop();
                if (dist[v] != d) continue;
                for (int i = 0; i < g[v].size(); i++) {
                    auto &e = g[v][i];
                    if (e.cap > 0 && dist[e.to] > d + e.cost + pot[v] - pot[e.to]) {
                        dist[e.to] = d + e.cost + pot[v] - pot[e.to];
                        prev_v[e.to] = v;
                        prev_e[e.to] = i;
                        pq.push({dist[e.to], e.to});
                    }
                }
            }
            if (dist[t] == INF_COST) break;
            for (int v = 0; v < n; v++) {
                if (dist[v] < INF_COST) pot[v] += dist[v];
            }
            Flow add = f;
            for (int v = t; v != s; v = prev_v[v])
                add = min(add, g[prev_v[v]][prev_e[v]].cap);
            f -= add;
            fl += add;
            cost += add * pot[t];
            for (int v = t; v != s; v = prev_v[v]) {
                auto &e = g[prev_v[v]][prev_e[v]];
                e.cap -= add;
                g[v][e.rev].cap += add;
            }
        }
        return {fl, cost};
    }
};

int main(){
    int n = Cin();
    int source = n, sink = n + 1;
    MinCostFlow<int, ll> mcf(sink + 1);
    vector<int> in(n), out(n);
    int base = 0;
    for (int i = 0; i < n; i++){
        int k = Cin();
        out[i] = k;
        for (int j = 0; j < k; j++){
            int t = Cin()-1, c = Cin();
            base += c;
            mcf.add_edge(i, t, INF, c);
            in[t]++;
        }
    }
    for (int i = 0; i < n; i++){
        if (in[i] - out[i] > 0) mcf.add_edge(source, i, in[i] - out[i], 0);
        if (out[i] - in[i] > 0) mcf.add_edge(i, sink, out[i] - in[i], 0);
    }
    mcf.add_edge(source, 0, INF, 0);
    auto [flow, cost] = mcf.flow(source, sink);
    Cout(base + cost);
    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 6360
final_rank: 4

code_snippet: // AOJ #2627 Multi Path Story
// 2025.3.26

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int INF = 1e9;

template<typename Flow, typename Cost>
struct MinCostFlow {
    struct Edge {
        int to, rev;
        Flow cap;
        Cost cost;
    };
    int n;
    vector<vector<Edge>> g;
    vector<Cost> pot, dist;
    vector<int> prev_v, prev_e;
    const Cost INF_COST;

    MinCostFlow(int n) : n(n), g(n), INF_COST((Cost)1LL << 60) {
        pot.assign(n, 0);
        dist.assign(n, INF_COST);
        prev_v.assign(n, -1);
        prev_e.assign(n, -1);
    }

    void add_edge(int s, int t, Flow cap, Cost cost) {
        g[s].push_back({t, (int)g[t].size(), cap, cost});
        g[t].push_back({s, (int)g[s].size()-1, 0, -cost});
    }

    pair<Flow, Cost> flow(int s, int t, Flow f = numeric_limits<Flow>::max()) {
        Flow fl = 0;
        Cost cost = 0;
        while (f > 0) {
            fill(dist.begin(), dist.end(), INF_COST);
            dist[s] = 0;
            using P = pair<Cost, int>;
            priority_queue<P, vector<P>, greater<P>> pq;
            pq.push({0, s});
            while (!pq.empty()) {
                auto [d, v] = pq.top();
                pq.pop();
                if (dist[v] != d) continue;
                for (int i = 0; i < g[v].size(); i++) {
                    auto &e = g[v][i];
                    if (e.cap > 0 && dist[e.to] > d + e.cost + pot[v] - pot[e.to]) {
                        dist[e.to] = d + e.cost + pot[v] - pot[e.to];
                        prev_v[e.to] = v;
                        prev_e[e.to] = i;
                        pq.push({dist[e.to], e.to});
                    }
                }
            }
            if (dist[t] == INF_COST) break;
            for (int v = 0; v < n; v++) {
                if (dist[v] < INF_COST) pot[v] += dist[v];
            }
            Flow add = f;
            for (int v = t; v != s; v = prev_v[v])
                add = min(add, g[prev_v[v]][prev_e[v]].cap);
            f -= add;
            fl += add;
            cost += add * pot[t];
            for (int v = t; v != s; v = prev_v[v]) {
                auto &e = g[prev_v[v]][prev_e[v]];
                e.cap -= add;
                g[v][e.rev].cap += add;
            }
        }
        return {fl, cost};
    }
};

int main(){
    int n = Cin();
    int source = n, sink = n + 1;
    MinCostFlow<int, ll> mcf(sink + 1);
    vector<int> in(n), out(n);
    int base = 0;
    for (int i = 0; i < n; i++){
        int k = Cin();
        out[i] = k;
        for (int j = 0; j < k; j++){
            int t = Cin()-1, c = Cin();
            base += c;
            mcf.add_edge(i, t, INF, c);
            in[t]++;
        }
    }
    for (int i = 0; i < n; i++){
        if (in[i] - out[i] > 0) mcf.add_edge(source, i, in[i] - out[i], 0);
        if (out[i] - in[i] > 0) mcf.add_edge(i, sink, out[i] - in[i], 0);
    }
    mcf.add_edge(source, 0, INF, 0);
    auto [flow, cost] = mcf.flow(source, sink);
    Cout(base + cost);
    return 0;
}
accuracy: 0.9807692307692307
time_ms: 150
memory_kb: 6444
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()
#define REPname(a,b,c,d,...) d
#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i,l,r) for(int i = l; i < r; i++)
#define REP1(i, x) REP2(i,0,x)
#define REP0(x) REP1(SPJ, x)
#define sz(x) int(x.size())

template <class T>
using V=vector<T>;

template <class T>
using VV=vector<V<T>>;

template<class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long ;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using pii = pair<int, int>;
using vvll = V<vll>;


const ll INF = numeric_limits<ll>::max() / 4;
constexpr int inf = 1e9;
template<class T>
inline bool chmax(T &a, T b){
	return a < b ? a=b, 1 : 0;
}
template <class T>
inline bool chmin(T &a, T b) {
	return a > b ? a = b, 1 : 0;
}


// template <c0lass T>
void view(ll x) {
	if(x > INF / 2) cerr << "INF";
	else cerr << x;
}


template <class T>
void view(T x) {
	cerr << x;
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ", ";}
	cerr << "}";
}


template <class T>
void view(VV<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ",\n";}
	cerr << "}";
	cerr << endl;
}


// template <c0lass T>
void view(int x) {
	cerr << x;
}

#ifdef LOCAL
void debug_out() {}
template <class T>
void debug_out(T x) {
	view(x);
}
template <class H, class... T>
void debug_out(H h, T... t) {
	view(h);
	cerr << ", ";
	debug_out(t...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
using vvi = V<vi>;



#include <bits/extc++.h> /// include-line, keep-include

typedef vector<ll> VL;

struct MCMF {
	int N;
	vector<vi> ed, red;
	vector<VL> cap, flow, cost;
	vi seen;
	VL dist, pi;
	vector<pii> par;

	MCMF(int N) :
		N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap),
		seen(N), dist(N), pi(N), par(N) {}

	void addEdge(int from, int to, ll cap, ll cost) {
		this->cap[from][to] = cap;
		this->cost[from][to] = cost;
		ed[from].push_back(to);
		red[to].push_back(from);
	}

	void path(int s) {
		fill(all(seen), 0);
		fill(all(dist), INF);
		dist[s] = 0; ll di;

		__gnu_pbds::priority_queue<pair<ll, int>> q;
		vector<decltype(q)::point_iterator> its(N);
		q.push({0, s});

		auto relax = [&](int i, ll cap, ll cost, int dir) {
			ll val = di - pi[i] + cost;
			if (cap && val < dist[i]) {
				dist[i] = val;
				par[i] = {s, dir};
				if (its[i] == q.end()) its[i] = q.push({-dist[i], i});
				else q.modify(its[i], {-dist[i], i});
			}
		};

		while (!q.empty()) {
			s = q.top().second; q.pop();
			seen[s] = 1; di = dist[s] + pi[s];
			for (int i : ed[s]) if (!seen[i])
				relax(i, cap[s][i] - flow[s][i], cost[s][i], 1);
			for (int i : red[s]) if (!seen[i])
				relax(i, flow[i][s], -cost[i][s], 0);
		}
		rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF);
	}

	pair<ll, ll> maxflow(int s, int t) {
		ll totflow = 0, totcost = 0;
		while (path(s), seen[t]) {
			ll fl = INF;
			for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p)
				fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]);
			totflow += fl;
			for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p)
				if (r) flow[p][x] += fl;
				else flow[x][p] -= fl;
		}
		rep(i,0,N) rep(j,0,N) totcost += cost[i][j] * flow[i][j];
		return {totflow, totcost};
	}

	// If some costs can be negative, call this before maxflow:
	void setpi(int s) { // (otherwise, leave this out)
		fill(all(pi), INF); pi[s] = 0;
		int it = N, ch = 1; ll v;
		while (ch-- && it--)
			rep(i,0,N) if (pi[i] != INF)
				for (int to : ed[i]) if (cap[i][to])
					if ((v = pi[i] + cost[i][to]) < pi[to])
						pi[to] = v, ch = 1;
		assert(it >= 0); // negative cost cycle
	}
};



ll solve(int n){
	// vector<V<pair<int, ll>>> g(n);
	vector<ll> supply(n);
	const int src = n;
	const int trm = src + 1;
	MCMF g(trm + 1);

	const ll f_max = n * n + 10;
	ll ans = 0;
	rep(from, n) {
		int k; cin >> k;
		rep(k) {
			int nxt;
			cin >> nxt;
			nxt--;
			ll cost ; cin >> cost;
			// g.at(from).emplace_back(nxt, cost);
			supply[from]--;
			supply[nxt]++;
			g.addEdge(from, nxt, f_max, cost);
			ans += cost;
		}
	}

	rep(i, n) {
		int sup = supply[i];
		if(i && sup < 0) {
			g.addEdge(i, trm, -sup, 0LL);
		} else if(i == 0) {
			g.addEdge(src, i, f_max, 0LL);
		} else if(sup > 0) {
			g.addEdge(src, i, sup, 0LL);
		}
	}

	auto pr = g.maxflow(src, trm);

	return ans + pr.second;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	srand((unsigned)time(NULL));
	int n;
	while(cin >> n && n) cout << solve(n) << '\n';
}
accuracy: 0.11538461538461539
time_ms: 110
memory_kb: 24852
final_rank: 17

code_snippet: #line 1 "b.cpp"
#include <bits/stdc++.h>
using namespace std;
#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()
#define REPname(a,b,c,d,...) d
#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i,l,r) for(int i = l; i < r; i++)
#define REP1(i, x) REP2(i,0,x)
#define REP0(x) REP1(SPJ, x)
#define sz(x) int(x.size())

template <class T>
using V=vector<T>;

template <class T>
using VV=vector<V<T>>;

template<class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long ;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using pii = pair<int, int>;
using vvll = V<vll>;


const ll INF = numeric_limits<ll>::max() / 4;
constexpr int inf = 1e9;
template<class T>
inline bool chmax(T &a, T b){
	return a < b ? a=b, 1 : 0;
}
template <class T>
inline bool chmin(T &a, T b) {
	return a > b ? a = b, 1 : 0;
}


// template <c0lass T>
void view(ll x) {
	if(x > INF / 2) cerr << "INF";
	else cerr << x;
}


template <class T>
void view(T x) {
	cerr << x;
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ", ";}
	cerr << "}";
}


template <class T>
void view(VV<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ",\n";}
	cerr << "}";
	cerr << endl;
}


// template <c0lass T>
void view(int x) {
	cerr << x;
}

#ifdef LOCAL
void debug_out() {}
template <class T>
void debug_out(T x) {
	view(x);
}
template <class H, class... T>
void debug_out(H h, T... t) {
	view(h);
	cerr << ", ";
	debug_out(t...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
using vvi = V<vi>;


#line 1 "atcoder/mincostflow.hpp"



#line 9 "atcoder/mincostflow.hpp"

#line 1 "atcoder/internal_csr.hpp"



#line 7 "atcoder/internal_csr.hpp"

namespace atcoder {
namespace internal {

template <class E> struct csr {
    std::vector<int> start;
    std::vector<E> elist;
    explicit csr(int n, const std::vector<std::pair<int, E>>& edges)
        : start(n + 1), elist(edges.size()) {
        for (auto e : edges) {
            start[e.first + 1]++;
        }
        for (int i = 1; i <= n; i++) {
            start[i] += start[i - 1];
        }
        auto counter = start;
        for (auto e : edges) {
            elist[counter[e.first]++] = e.second;
        }
    }
};

}  // namespace internal

}  // namespace atcoder


#line 1 "atcoder/internal_queue.hpp"



#line 5 "atcoder/internal_queue.hpp"

namespace atcoder {

namespace internal {

template <class T> struct simple_queue {
    std::vector<T> payload;
    int pos = 0;
    void reserve(int n) { payload.reserve(n); }
    int size() const { return int(payload.size()) - pos; }
    bool empty() const { return pos == int(payload.size()); }
    void push(const T& t) { payload.push_back(t); }
    T& front() { return payload[pos]; }
    void clear() {
        payload.clear();
        pos = 0;
    }
    void pop() { pos++; }
};

}  // namespace internal

}  // namespace atcoder


#line 12 "atcoder/mincostflow.hpp"

namespace atcoder {

template <class Cap, class Cost> struct mcf_graph {
  public:
    mcf_graph() {}
    explicit mcf_graph(int n) : _n(n) {}

    int add_edge(int from, int to, Cap cap, Cost cost) {
        assert(0 <= from && from < _n);
        assert(0 <= to && to < _n);
        assert(0 <= cap);
        assert(0 <= cost);
        int m = int(_edges.size());
        _edges.push_back({from, to, cap, 0, cost});
        return m;
    }

    struct edge {
        int from, to;
        Cap cap, flow;
        Cost cost;
    };

    edge get_edge(int i) {
        int m = int(_edges.size());
        assert(0 <= i && i < m);
        return _edges[i];
    }
    std::vector<edge> edges() { return _edges; }

    std::pair<Cap, Cost> flow(int s, int t) {
        return flow(s, t, std::numeric_limits<Cap>::max());
    }
    std::pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {
        return slope(s, t, flow_limit).back();
    }
    std::vector<std::pair<Cap, Cost>> slope(int s, int t) {
        return slope(s, t, std::numeric_limits<Cap>::max());
    }
    std::vector<std::pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {
        assert(0 <= s && s < _n);
        assert(0 <= t && t < _n);
        assert(s != t);

        int m = int(_edges.size());
        std::vector<int> edge_idx(m);

        auto g = [&]() {
            std::vector<int> degree(_n), redge_idx(m);
            std::vector<std::pair<int, _edge>> elist;
            elist.reserve(2 * m);
            for (int i = 0; i < m; i++) {
                auto e = _edges[i];
                edge_idx[i] = degree[e.from]++;
                redge_idx[i] = degree[e.to]++;
                elist.push_back({e.from, {e.to, -1, e.cap - e.flow, e.cost}});
                elist.push_back({e.to, {e.from, -1, e.flow, -e.cost}});
            }
            auto _g = internal::csr<_edge>(_n, elist);
            for (int i = 0; i < m; i++) {
                auto e = _edges[i];
                edge_idx[i] += _g.start[e.from];
                redge_idx[i] += _g.start[e.to];
                _g.elist[edge_idx[i]].rev = redge_idx[i];
                _g.elist[redge_idx[i]].rev = edge_idx[i];
            }
            return _g;
        }();

        auto result = slope(g, s, t, flow_limit);

        for (int i = 0; i < m; i++) {
            auto e = g.elist[edge_idx[i]];
            _edges[i].flow = _edges[i].cap - e.cap;
        }

        return result;
    }

  private:
    int _n;
    std::vector<edge> _edges;

    // inside edge
    struct _edge {
        int to, rev;
        Cap cap;
        Cost cost;
    };

    std::vector<std::pair<Cap, Cost>> slope(internal::csr<_edge>& g,
                                            int s,
                                            int t,
                                            Cap flow_limit) {
        // variants (C = maxcost):
        // -(n-1)C <= dual[s] <= dual[i] <= dual[t] = 0
        // reduced cost (= e.cost + dual[e.from] - dual[e.to]) >= 0 for all edge

        // dual_dist[i] = (dual[i], dist[i])
        std::vector<std::pair<Cost, Cost>> dual_dist(_n);
        std::vector<int> prev_e(_n);
        std::vector<bool> vis(_n);
        struct Q {
            Cost key;
            int to;
            bool operator<(Q r) const { return key > r.key; }
        };
        std::vector<int> que_min;
        std::vector<Q> que;
        auto dual_ref = [&]() {
            for (int i = 0; i < _n; i++) {
                dual_dist[i].second = std::numeric_limits<Cost>::max();
            }
            std::fill(vis.begin(), vis.end(), false);
            que_min.clear();
            que.clear();

            // que[0..heap_r) was heapified
            size_t heap_r = 0;

            dual_dist[s].second = 0;
            que_min.push_back(s);
            while (!que_min.empty() || !que.empty()) {
                int v;
                if (!que_min.empty()) {
                    v = que_min.back();
                    que_min.pop_back();
                } else {
                    while (heap_r < que.size()) {
                        heap_r++;
                        std::push_heap(que.begin(), que.begin() + heap_r);
                    }
                    v = que.front().to;
                    std::pop_heap(que.begin(), que.end());
                    que.pop_back();
                    heap_r--;
                }
                if (vis[v]) continue;
                vis[v] = true;
                if (v == t) break;
                // dist[v] = shortest(s, v) + dual[s] - dual[v]
                // dist[v] >= 0 (all reduced cost are positive)
                // dist[v] <= (n-1)C
                Cost dual_v = dual_dist[v].first, dist_v = dual_dist[v].second;
                for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                    auto e = g.elist[i];
                    if (!e.cap) continue;
                    // |-dual[e.to] + dual[v]| <= (n-1)C
                    // cost <= C - -(n-1)C + 0 = nC
                    Cost cost = e.cost - dual_dist[e.to].first + dual_v;
                    if (dual_dist[e.to].second - dist_v > cost) {
                        Cost dist_to = dist_v + cost;
                        dual_dist[e.to].second = dist_to;
                        prev_e[e.to] = e.rev;
                        if (dist_to == dist_v) {
                            que_min.push_back(e.to);
                        } else {
                            que.push_back(Q{dist_to, e.to});
                        }
                    }
                }
            }
            if (!vis[t]) {
                return false;
            }

            for (int v = 0; v < _n; v++) {
                if (!vis[v]) continue;
                // dual[v] = dual[v] - dist[t] + dist[v]
                //         = dual[v] - (shortest(s, t) + dual[s] - dual[t]) +
                //         (shortest(s, v) + dual[s] - dual[v]) = - shortest(s,
                //         t) + dual[t] + shortest(s, v) = shortest(s, v) -
                //         shortest(s, t) >= 0 - (n-1)C
                dual_dist[v].first -= dual_dist[t].second - dual_dist[v].second;
            }
            return true;
        };
        Cap flow = 0;
        Cost cost = 0, prev_cost_per_flow = -1;
        std::vector<std::pair<Cap, Cost>> result = {{Cap(0), Cost(0)}};
        while (flow < flow_limit) {
            if (!dual_ref()) break;
            Cap c = flow_limit - flow;
            for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
                c = std::min(c, g.elist[g.elist[prev_e[v]].rev].cap);
            }
            for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
                auto& e = g.elist[prev_e[v]];
                e.cap += c;
                g.elist[e.rev].cap -= c;
            }
            Cost d = -dual_dist[s].first;
            flow += c;
            cost += c * d;
            if (prev_cost_per_flow == d) {
                result.pop_back();
            }
            result.push_back({flow, cost});
            prev_cost_per_flow = d;
        }
        return result;
    }
};

}  // namespace atcoder


#line 100 "b.cpp"
using MCMF = atcoder::mcf_graph<ll, ll>;

ll solve(int n){
	// vector<V<pair<int, ll>>> g(n);
	vector<ll> supply(n);
	const int src = n;
	const int trm = src + 1;
	MCMF g(trm + 1);


	ll ans  = 0;
	rep(from, n) {
		int k; cin >> k;
		rep(k) {
			int nxt;
			cin >> nxt;
			nxt--;
			ll cost ; cin >> cost;
			// g.at(from).emplace_back(nxt, cost);
			supply[from]--;
			supply[nxt]++;
			// g.addEdge(from, nxt, INF, cost);
			g.add_edge(from, nxt, INF, cost);
			ans += cost;
		}
	}

	rep(i, n) {
		int sup = supply[i];
		if(i && sup < 0) {
			g.add_edge(i, trm, -sup, 0LL);
		} else if(i == 0) {
			g.add_edge(src, i, INF, 0LL);
		} else if(sup > 0) {
			g.add_edge(src, i, sup, 0LL);
		}
	}

	auto pr = g.flow(src, trm);

	return ans + pr.second;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	srand((unsigned)time(NULL));
	int n;
	while(cin >> n && n) cout << solve(n) << '\n';
}
accuracy: 1
time_ms: 60
memory_kb: 10528
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()
#define REPname(a,b,c,d,...) d
#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i,l,r) for(int i = l; i < r; i++)
#define REP1(i, x) REP2(i,0,x)
#define REP0(x) REP1(SPJ, x)
#define sz(x) int(x.size())

template <class T>
using V=vector<T>;

template <class T>
using VV=vector<V<T>>;

template<class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long ;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using pii = pair<int, int>;
using vvll = V<vll>;


const ll INF = numeric_limits<ll>::max() / 4;
constexpr int inf = 1e9;
template<class T>
inline bool chmax(T &a, T b){
	return a < b ? a=b, 1 : 0;
}
template <class T>
inline bool chmin(T &a, T b) {
	return a > b ? a = b, 1 : 0;
}


// template <c0lass T>
void view(ll x) {
	if(x > INF / 2) cerr << "INF";
	else cerr << x;
}


template <class T>
void view(T x) {
	cerr << x;
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ", ";}
	cerr << "}";
}


template <class T>
void view(VV<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ",\n";}
	cerr << "}";
	cerr << endl;
}


// template <c0lass T>
void view(int x) {
	cerr << x;
}

#ifdef LOCAL
void debug_out() {}
template <class T>
void debug_out(T x) {
	view(x);
}
template <class H, class... T>
void debug_out(H h, T... t) {
	view(h);
	cerr << ", ";
	debug_out(t...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
using vvi = V<vi>;



#include <bits/extc++.h> /// include-line, keep-include

typedef vector<ll> VL;

struct MCMF {
	int N;
	vector<vi> ed, red;
	vector<VL> cap, flow, cost;
	vi seen;
	VL dist, pi;
	vector<pii> par;

	MCMF(int N) :
		N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap),
		seen(N), dist(N), pi(N), par(N) {}

	void addEdge(int from, int to, ll cap, ll cost) {
		this->cap[from][to] = cap;
		this->cost[from][to] = cost;
		ed[from].push_back(to);
		red[to].push_back(from);
	}

	void path(int s) {
		fill(all(seen), 0);
		fill(all(dist), INF);
		dist[s] = 0; ll di;

		__gnu_pbds::priority_queue<pair<ll, int>> q;
		vector<decltype(q)::point_iterator> its(N);
		q.push({0, s});

		auto relax = [&](int i, ll cap, ll cost, int dir) {
			ll val = di - pi[i] + cost;
			if (cap && val < dist[i]) {
				dist[i] = val;
				par[i] = {s, dir};
				if (its[i] == q.end()) its[i] = q.push({-dist[i], i});
				else q.modify(its[i], {-dist[i], i});
			}
		};

		while (!q.empty()) {
			s = q.top().second; q.pop();
			seen[s] = 1; di = dist[s] + pi[s];
			for (int i : ed[s]) if (!seen[i])
				relax(i, cap[s][i] - flow[s][i], cost[s][i], 1);
			for (int i : red[s]) if (!seen[i])
				relax(i, flow[i][s], -cost[i][s], 0);
		}
		rep(i,0,N) pi[i] = min(pi[i] + dist[i], INF);
	}

	pair<ll, ll> maxflow(int s, int t) {
		ll totflow = 0, totcost = 0;
		while (path(s), seen[t]) {
			ll fl = INF;
			for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p)
				fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]);
			totflow += fl;
			for (int p,r,x = t; tie(p,r) = par[x], x != s; x = p)
				if (r) flow[p][x] += fl;
				else flow[x][p] -= fl;
		}
		rep(i,0,N) rep(j,0,N) totcost += cost[i][j] * flow[i][j];
		return {totflow, totcost};
	}

	// If some costs can be negative, call this before maxflow:
	void setpi(int s) { // (otherwise, leave this out)
		fill(all(pi), INF); pi[s] = 0;
		int it = N, ch = 1; ll v;
		while (ch-- && it--)
			rep(i,0,N) if (pi[i] != INF)
				for (int to : ed[i]) if (cap[i][to])
					if ((v = pi[i] + cost[i][to]) < pi[to])
						pi[to] = v, ch = 1;
		assert(it >= 0); // negative cost cycle
	}
};



ll solve(int n){
	// vector<V<pair<int, ll>>> g(n);
	vector<ll> supply(n);
	const int src = n;
	const int trm = src + 1;
	MCMF g(trm + 1);


	ll ans  = 0;
	rep(from, n) {
		int k; cin >> k;
		rep(k) {
			int nxt;
			cin >> nxt;
			nxt--;
			ll cost ; cin >> cost;
			// g.at(from).emplace_back(nxt, cost);
			supply[from]--;
			supply[nxt]++;
			g.addEdge(from, nxt, INF, cost);
			ans += cost;
		}
	}

	rep(i, n) {
		int sup = supply[i];
		if(i && sup < 0) {
			g.addEdge(i, trm, -sup, 0LL);
		} else if(i == 0) {
			g.addEdge(src, i, INF, 0LL);
		} else if(sup > 0) {
			g.addEdge(src, i, sup, 0LL);
		}
	}

	auto pr = g.maxflow(src, trm);

	return ans + pr.second;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	srand((unsigned)time(NULL));
	int n;
	while(cin >> n && n) cout << solve(n) << '\n';
}
accuracy: 0.11538461538461539
time_ms: 110
memory_kb: 25156
final_rank: 19

code_snippet: #line 1 "SPJ-Library/icpc/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()

#define REPname(a, b, c, d, ...) d

#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i, l, r) for(int i = l; i < r; ++i)
#define REP1(i, x) REP2(i, 0, x)
#define REP0(x) REP1(SPJ, x)

#define drep(...) REPname(__VA_ARGS__, DREP2, DREP1)(__VA_ARGS__)
#define DREP2(i, l, r) for(int i = r - 1; i >= l; --i)
#define DREP1(i, x) DREP2(i, 0, x)

template <class T>
using V = vector<T>;
template <class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long;
using vi = V<int>;
constexpr ll INF = 1e18;
constexpr int inf = 1e9;

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}

template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void view(ll e) {
	if(e >= INF / 2)
		cerr << "INF";
	else if(e <= -INF / 2)
		cerr << "-INF";
	else
		cerr << e;
}

template <typename T>
void view(T e) {
	cerr << e;
}

template <typename T, typename U>
void view(pair<T, U> p) {
	cerr << '(';
	view(p.first);
	cerr << ", ";
	view(p.second);
	cerr << ')';
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	auto it = v.begin();
	while(it != v.end()) {
		cerr << "\t";
		view(*it++);
		cerr << ", ";
	}
	cerr << '}';
}

template <class T>
void view(V<V<T>> vv) {
	cerr << "{";
	auto it = vv.begin();
	while(it != vv.end()) {
		cerr << "\t";
		view(*it++);
		cerr << ",\n";
	}
	cerr << '}';
}

template <class T, class U>
void view(map<T, U> m) {
	cerr << "{\n";
	for(auto it = m.begin(); it != m.end(); it++) {
		cerr << "\t[";
		view(it->first);
		cerr << "] : ";
		view(it->second);
		cerr << '\n';
	}
	cerr << "}";
}

#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(T x) {
	view(x);
}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	view(H);
	cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif

// void solve(int n) {}
// int main() {
// 	int n;
// 	cin >> n;
// 	while(cin >> n && n) solve(n);
// }
#line 2 "b.cpp"

using VL = V<ll>;
using pii = pair<int, int>;

#line 1 "atcoder/mincostflow.hpp"



#line 9 "atcoder/mincostflow.hpp"

#line 1 "atcoder/internal_csr.hpp"



#line 7 "atcoder/internal_csr.hpp"

namespace atcoder {
namespace internal {

template <class E> struct csr {
    std::vector<int> start;
    std::vector<E> elist;
    explicit csr(int n, const std::vector<std::pair<int, E>>& edges)
        : start(n + 1), elist(edges.size()) {
        for (auto e : edges) {
            start[e.first + 1]++;
        }
        for (int i = 1; i <= n; i++) {
            start[i] += start[i - 1];
        }
        auto counter = start;
        for (auto e : edges) {
            elist[counter[e.first]++] = e.second;
        }
    }
};

}  // namespace internal

}  // namespace atcoder


#line 1 "atcoder/internal_queue.hpp"



#line 5 "atcoder/internal_queue.hpp"

namespace atcoder {

namespace internal {

template <class T> struct simple_queue {
    std::vector<T> payload;
    int pos = 0;
    void reserve(int n) { payload.reserve(n); }
    int size() const { return int(payload.size()) - pos; }
    bool empty() const { return pos == int(payload.size()); }
    void push(const T& t) { payload.push_back(t); }
    T& front() { return payload[pos]; }
    void clear() {
        payload.clear();
        pos = 0;
    }
    void pop() { pos++; }
};

}  // namespace internal

}  // namespace atcoder


#line 12 "atcoder/mincostflow.hpp"

namespace atcoder {

template <class Cap, class Cost> struct mcf_graph {
  public:
    mcf_graph() {}
    explicit mcf_graph(int n) : _n(n) {}

    int add_edge(int from, int to, Cap cap, Cost cost) {
        assert(0 <= from && from < _n);
        assert(0 <= to && to < _n);
        assert(0 <= cap);
        assert(0 <= cost);
        int m = int(_edges.size());
        _edges.push_back({from, to, cap, 0, cost});
        return m;
    }

    struct edge {
        int from, to;
        Cap cap, flow;
        Cost cost;
    };

    edge get_edge(int i) {
        int m = int(_edges.size());
        assert(0 <= i && i < m);
        return _edges[i];
    }
    std::vector<edge> edges() { return _edges; }

    std::pair<Cap, Cost> flow(int s, int t) {
        return flow(s, t, std::numeric_limits<Cap>::max());
    }
    std::pair<Cap, Cost> flow(int s, int t, Cap flow_limit) {
        return slope(s, t, flow_limit).back();
    }
    std::vector<std::pair<Cap, Cost>> slope(int s, int t) {
        return slope(s, t, std::numeric_limits<Cap>::max());
    }
    std::vector<std::pair<Cap, Cost>> slope(int s, int t, Cap flow_limit) {
        assert(0 <= s && s < _n);
        assert(0 <= t && t < _n);
        assert(s != t);

        int m = int(_edges.size());
        std::vector<int> edge_idx(m);

        auto g = [&]() {
            std::vector<int> degree(_n), redge_idx(m);
            std::vector<std::pair<int, _edge>> elist;
            elist.reserve(2 * m);
            for (int i = 0; i < m; i++) {
                auto e = _edges[i];
                edge_idx[i] = degree[e.from]++;
                redge_idx[i] = degree[e.to]++;
                elist.push_back({e.from, {e.to, -1, e.cap - e.flow, e.cost}});
                elist.push_back({e.to, {e.from, -1, e.flow, -e.cost}});
            }
            auto _g = internal::csr<_edge>(_n, elist);
            for (int i = 0; i < m; i++) {
                auto e = _edges[i];
                edge_idx[i] += _g.start[e.from];
                redge_idx[i] += _g.start[e.to];
                _g.elist[edge_idx[i]].rev = redge_idx[i];
                _g.elist[redge_idx[i]].rev = edge_idx[i];
            }
            return _g;
        }();

        auto result = slope(g, s, t, flow_limit);

        for (int i = 0; i < m; i++) {
            auto e = g.elist[edge_idx[i]];
            _edges[i].flow = _edges[i].cap - e.cap;
        }

        return result;
    }

  private:
    int _n;
    std::vector<edge> _edges;

    // inside edge
    struct _edge {
        int to, rev;
        Cap cap;
        Cost cost;
    };

    std::vector<std::pair<Cap, Cost>> slope(internal::csr<_edge>& g,
                                            int s,
                                            int t,
                                            Cap flow_limit) {
        // variants (C = maxcost):
        // -(n-1)C <= dual[s] <= dual[i] <= dual[t] = 0
        // reduced cost (= e.cost + dual[e.from] - dual[e.to]) >= 0 for all edge

        // dual_dist[i] = (dual[i], dist[i])
        std::vector<std::pair<Cost, Cost>> dual_dist(_n);
        std::vector<int> prev_e(_n);
        std::vector<bool> vis(_n);
        struct Q {
            Cost key;
            int to;
            bool operator<(Q r) const { return key > r.key; }
        };
        std::vector<int> que_min;
        std::vector<Q> que;
        auto dual_ref = [&]() {
            for (int i = 0; i < _n; i++) {
                dual_dist[i].second = std::numeric_limits<Cost>::max();
            }
            std::fill(vis.begin(), vis.end(), false);
            que_min.clear();
            que.clear();

            // que[0..heap_r) was heapified
            size_t heap_r = 0;

            dual_dist[s].second = 0;
            que_min.push_back(s);
            while (!que_min.empty() || !que.empty()) {
                int v;
                if (!que_min.empty()) {
                    v = que_min.back();
                    que_min.pop_back();
                } else {
                    while (heap_r < que.size()) {
                        heap_r++;
                        std::push_heap(que.begin(), que.begin() + heap_r);
                    }
                    v = que.front().to;
                    std::pop_heap(que.begin(), que.end());
                    que.pop_back();
                    heap_r--;
                }
                if (vis[v]) continue;
                vis[v] = true;
                if (v == t) break;
                // dist[v] = shortest(s, v) + dual[s] - dual[v]
                // dist[v] >= 0 (all reduced cost are positive)
                // dist[v] <= (n-1)C
                Cost dual_v = dual_dist[v].first, dist_v = dual_dist[v].second;
                for (int i = g.start[v]; i < g.start[v + 1]; i++) {
                    auto e = g.elist[i];
                    if (!e.cap) continue;
                    // |-dual[e.to] + dual[v]| <= (n-1)C
                    // cost <= C - -(n-1)C + 0 = nC
                    Cost cost = e.cost - dual_dist[e.to].first + dual_v;
                    if (dual_dist[e.to].second - dist_v > cost) {
                        Cost dist_to = dist_v + cost;
                        dual_dist[e.to].second = dist_to;
                        prev_e[e.to] = e.rev;
                        if (dist_to == dist_v) {
                            que_min.push_back(e.to);
                        } else {
                            que.push_back(Q{dist_to, e.to});
                        }
                    }
                }
            }
            if (!vis[t]) {
                return false;
            }

            for (int v = 0; v < _n; v++) {
                if (!vis[v]) continue;
                // dual[v] = dual[v] - dist[t] + dist[v]
                //         = dual[v] - (shortest(s, t) + dual[s] - dual[t]) +
                //         (shortest(s, v) + dual[s] - dual[v]) = - shortest(s,
                //         t) + dual[t] + shortest(s, v) = shortest(s, v) -
                //         shortest(s, t) >= 0 - (n-1)C
                dual_dist[v].first -= dual_dist[t].second - dual_dist[v].second;
            }
            return true;
        };
        Cap flow = 0;
        Cost cost = 0, prev_cost_per_flow = -1;
        std::vector<std::pair<Cap, Cost>> result = {{Cap(0), Cost(0)}};
        while (flow < flow_limit) {
            if (!dual_ref()) break;
            Cap c = flow_limit - flow;
            for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
                c = std::min(c, g.elist[g.elist[prev_e[v]].rev].cap);
            }
            for (int v = t; v != s; v = g.elist[prev_e[v]].to) {
                auto& e = g.elist[prev_e[v]];
                e.cap += c;
                g.elist[e.rev].cap -= c;
            }
            Cost d = -dual_dist[s].first;
            flow += c;
            cost += c * d;
            if (prev_cost_per_flow == d) {
                result.pop_back();
            }
            result.push_back({flow, cost});
            prev_cost_per_flow = d;
        }
        return result;
    }
};

}  // namespace atcoder


#line 7 "b.cpp"

void solve(int n) {
	vector<int> supply(n, 0);
	ll ans = 0;
	int gsize = n + 2;
	int start = gsize - 2;
	int terminal = gsize - 1;
	atcoder::mcf_graph<ll, ll> mcf(gsize);

	rep(now, n) {
		int k;
		cin >> k;
		rep(i, k) {
			int nxt;
			ll cost;
			cin >> nxt >> cost;
			ans += cost;
			nxt--;
			supply[now]--;
			supply[nxt]++;
			mcf.add_edge(now, nxt, INF, cost);
		}
	}

	mcf.add_edge(start, 0, INF, 0LL);
	rep(i, 1, n) {
		debug(i, supply[i]);
		if(supply[i] < 0) {
			int need = -supply[i];
			mcf.add_edge(i, terminal, need, 0LL);
		} else if(supply[i] > 0) {
			int sup = supply[i];
			mcf.add_edge(start, i, sup, 0LL);
		}
	}

	auto res = mcf.flow(start, terminal);
	debug(res);
	ans += res.second;

	cout << ans << '\n';
}

int main() {
	int n;
	while(cin >> n) solve(n);

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 10652
final_rank: 7

code_snippet: #line 1 "SPJ-Library/icpc/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()

#define REPname(a, b, c, d, ...) d

#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i, l, r) for(int i = l; i < r; ++i)
#define REP1(i, x) REP2(i, 0, x)
#define REP0(x) REP1(SPJ, x)

#define drep(...) REPname(__VA_ARGS__, DREP2, DREP1)(__VA_ARGS__)
#define DREP2(i, l, r) for(int i = r - 1; i >= l; --i)
#define DREP1(i, x) DREP2(i, 0, x)

template <class T>
using V = vector<T>;
template <class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long;
using vi = V<int>;
constexpr ll INF = 1e18;
constexpr int inf = 1e9;

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}

template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void view(ll e) {
	if(e >= INF / 2)
		cerr << "INF";
	else if(e <= -INF / 2)
		cerr << "-INF";
	else
		cerr << e;
}

template <typename T>
void view(T e) {
	cerr << e;
}

template <typename T, typename U>
void view(pair<T, U> p) {
	cerr << '(';
	view(p.first);
	cerr << ", ";
	view(p.second);
	cerr << ')';
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	auto it = v.begin();
	while(it != v.end()) {
		cerr << "\t";
		view(*it++);
		cerr << ", ";
	}
	cerr << '}';
}

template <class T>
void view(V<V<T>> vv) {
	cerr << "{";
	auto it = vv.begin();
	while(it != vv.end()) {
		cerr << "\t";
		view(*it++);
		cerr << ",\n";
	}
	cerr << '}';
}

template <class T, class U>
void view(map<T, U> m) {
	cerr << "{\n";
	for(auto it = m.begin(); it != m.end(); it++) {
		cerr << "\t[";
		view(it->first);
		cerr << "] : ";
		view(it->second);
		cerr << '\n';
	}
	cerr << "}";
}

#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(T x) {
	view(x);
}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	view(H);
	cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif

// void solve(int n) {}
// int main() {
// 	int n;
// 	cin >> n;
// 	while(cin >> n && n) solve(n);
// }
#line 2 "a.cpp"

using VL = V<ll>;
using pii = pair<int, int>;

#include <bits/extc++.h>
struct MCMF {
	int N;
	vector<vi> ed, red;
	vector<VL> cap, flow, cost;
	vi seen;
	VL dist, pi;
	vector<pii> par;

	MCMF(int N) : N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap), seen(N), dist(N), pi(N), par(N) {}

	void addEdge(int from, int to, ll cap, ll cost) {
		this->cap[from][to] = cap;
		this->cost[from][to] = cost;
		ed[from].push_back(to);
		red[to].push_back(from);
	}

	void path(int s) {
		fill(all(seen), 0);
		fill(all(dist), INF);
		dist[s] = 0;
		ll di;

		__gnu_pbds::priority_queue<pair<ll, int>> q;
		vector<decltype(q)::point_iterator> its(N);
		q.push({0, s});

		auto relax = [&](int i, ll cap, ll cost, int dir) {
			ll val = di - pi[i] + cost;
			if(cap && val < dist[i]) {
				dist[i] = val;
				par[i] = {s, dir};
				if(its[i] == q.end())
					its[i] = q.push({-dist[i], i});
				else
					q.modify(its[i], {-dist[i], i});
			}
		};

		while(!q.empty()) {
			s = q.top().second;
			q.pop();
			seen[s] = 1;
			di = dist[s] + pi[s];
			for(int i : ed[s])
				if(!seen[i]) relax(i, cap[s][i] - flow[s][i], cost[s][i], 1);
			for(int i : red[s])
				if(!seen[i]) relax(i, flow[i][s], -cost[i][s], 0);
		}
		rep(i, 0, N) pi[i] = min(pi[i] + dist[i], INF);
	}

	pair<ll, ll> maxflow(int s, int t) {
		ll totflow = 0, totcost = 0;
		while(path(s), seen[t]) {
			ll fl = INF;
			for(int p, r, x = t; tie(p, r) = par[x], x != s; x = p) fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]);
			totflow += fl;
			for(int p, r, x = t; tie(p, r) = par[x], x != s; x = p)
				if(r)
					flow[p][x] += fl;
				else
					flow[x][p] -= fl;
		}
		rep(i, 0, N) rep(j, 0, N) totcost += cost[i][j] * flow[i][j];
		return {totflow, totcost};
	}

	// If some costs can be negative, call this before maxflow:
	void setpi(int s) {	 // (otherwise, leave this out)
		fill(all(pi), INF);
		pi[s] = 0;
		int it = N, ch = 1;
		ll v;
		while(ch-- && it--)
			rep(i, 0, N) if(pi[i] != INF) for(int to : ed[i]) if(cap[i][to]) if((v = pi[i] + cost[i][to]) < pi[to]) pi[to] = v, ch = 1;
		assert(it >= 0);  // negative cost cycle
	}
};

void solve(int n) {
	vector<int> supply(n, 0);
	ll ans = 0;
	int gsize = n + 2;
	int start = gsize - 2;
	int terminal = gsize - 1;
	MCMF mcf(gsize);

	rep(now, n) {
		int k;
		cin >> k;
		rep(i, k) {
			int nxt;
			ll cost;
			cin >> nxt >> cost;
			ans += cost;
			nxt--;
			supply[now]--;
			supply[nxt]++;
			mcf.addEdge(now, nxt, INF, cost);
		}
	}

	mcf.addEdge(start, 0, INF, 0LL);
	rep(i, 1, n) {
		debug(i, supply[i]);
		if(supply[i] < 0) {
			int need = -supply[i];
			mcf.addEdge(i, terminal, need, 0LL);
		} else if(supply[i] > 0) {
			int sup = supply[i];
			mcf.addEdge(start, i, sup, 0LL);
		}
	}

	auto res = mcf.maxflow(start, terminal);
	debug(res);
	ans += res.second;

	cout << ans << '\n';
}

int main() {
	int n;
	while(cin >> n) solve(n);

	return 0;
}
accuracy: 0.11538461538461539
time_ms: 120
memory_kb: 25060
final_rank: 18

code_snippet: #line 1 "SPJ-Library/icpc/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()

#define REPname(a, b, c, d, ...) d

#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i, l, r) for(int i = l; i < r; ++i)
#define REP1(i, x) REP2(i, 0, x)
#define REP0(x) REP1(SPJ, x)

#define drep(...) REPname(__VA_ARGS__, DREP2, DREP1)(__VA_ARGS__)
#define DREP2(i, l, r) for(int i = r - 1; i >= l; --i)
#define DREP1(i, x) DREP2(i, 0, x)

template <class T>
using V = vector<T>;
template <class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long;
using vi = V<int>;
constexpr ll INF = 1e18;
constexpr int inf = 1e9;

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}

template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void view(ll e) {
	if(e >= INF / 2)
		cerr << "INF";
	else if(e <= -INF / 2)
		cerr << "-INF";
	else
		cerr << e;
}

template <typename T>
void view(T e) {
	cerr << e;
}

template <typename T, typename U>
void view(pair<T, U> p) {
	cerr << '(';
	view(p.first);
	cerr << ", ";
	view(p.second);
	cerr << ')';
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	auto it = v.begin();
	while(it != v.end()) {
		cerr << "\t";
		view(*it++);
		cerr << ", ";
	}
	cerr << '}';
}

template <class T>
void view(V<V<T>> vv) {
	cerr << "{";
	auto it = vv.begin();
	while(it != vv.end()) {
		cerr << "\t";
		view(*it++);
		cerr << ",\n";
	}
	cerr << '}';
}

template <class T, class U>
void view(map<T, U> m) {
	cerr << "{\n";
	for(auto it = m.begin(); it != m.end(); it++) {
		cerr << "\t[";
		view(it->first);
		cerr << "] : ";
		view(it->second);
		cerr << '\n';
	}
	cerr << "}";
}

#ifdef LOCAL
void debug_out() {}
template <typename T>
void debug_out(T x) {
	view(x);
}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	view(H);
	cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif

// void solve(int n) {}
// int main() {
// 	int n;
// 	cin >> n;
// 	while(cin >> n && n) solve(n);
// }
#line 2 "a.cpp"

using VL = V<ll>;
using pii = pair<int, int>;

#include <bits/extc++.h>
struct MCMF {
	int N;
	vector<vi> ed, red;
	vector<VL> cap, flow, cost;
	vi seen;
	VL dist, pi;
	vector<pii> par;

	MCMF(int N) : N(N), ed(N), red(N), cap(N, VL(N)), flow(cap), cost(cap), seen(N), dist(N), pi(N), par(N) {}

	void addEdge(int from, int to, ll cap, ll cost) {
		debug(from, to, cap, cost);
		this->cap[from][to] = cap;
		this->cost[from][to] = cost;
		ed[from].push_back(to);
		red[to].push_back(from);
	}

	void path(int s) {
		fill(all(seen), 0);
		fill(all(dist), INF);
		dist[s] = 0;
		ll di;

		__gnu_pbds::priority_queue<pair<ll, int>> q;
		vector<decltype(q)::point_iterator> its(N);
		q.push({0, s});

		auto relax = [&](int i, ll cap, ll cost, int dir) {
			ll val = di - pi[i] + cost;
			if(cap && val < dist[i]) {
				dist[i] = val;
				par[i] = {s, dir};
				if(its[i] == q.end())
					its[i] = q.push({-dist[i], i});
				else
					q.modify(its[i], {-dist[i], i});
			}
		};

		while(!q.empty()) {
			s = q.top().second;
			q.pop();
			seen[s] = 1;
			di = dist[s] + pi[s];
			for(int i : ed[s])
				if(!seen[i]) relax(i, cap[s][i] - flow[s][i], cost[s][i], 1);
			for(int i : red[s])
				if(!seen[i]) relax(i, flow[i][s], -cost[i][s], 0);
		}
		rep(i, 0, N) pi[i] = min(pi[i] + dist[i], INF);
	}

	pair<ll, ll> maxflow(int s, int t) {
		ll totflow = 0, totcost = 0;
		while(path(s), seen[t]) {
			ll fl = INF;
			for(int p, r, x = t; tie(p, r) = par[x], x != s; x = p) fl = min(fl, r ? cap[p][x] - flow[p][x] : flow[x][p]);
			totflow += fl;
			for(int p, r, x = t; tie(p, r) = par[x], x != s; x = p)
				if(r)
					flow[p][x] += fl;
				else
					flow[x][p] -= fl;
		}
		rep(i, 0, N) rep(j, 0, N) totcost += cost[i][j] * flow[i][j];
		return {totflow, totcost};
	}

	// If some costs can be negative, call this before maxflow:
	void setpi(int s) {	 // (otherwise, leave this out)
		fill(all(pi), INF);
		pi[s] = 0;
		int it = N, ch = 1;
		ll v;
		while(ch-- && it--)
			rep(i, 0, N) if(pi[i] != INF) for(int to : ed[i]) if(cap[i][to]) if((v = pi[i] + cost[i][to]) < pi[to]) pi[to] = v, ch = 1;
		assert(it >= 0);  // negative cost cycle
	}
};

void solve(int n) {
	vector<vector<pair<int, ll>>> g(n);
	vector<int> supply(n, 0);
	ll ans = 0;
	rep(now, n) {
		auto& row = g[now];
		int k;
		cin >> k;
		rep(i, k) {
			int nxt;
			ll cost;
			cin >> nxt >> cost;
			ans += cost;
			nxt--;
			row.emplace_back(nxt, cost);
			supply[now]--;
			supply[nxt]++;
		}
	}
	vector<ll> dist(n, INF);
	constexpr int root = 0;
	priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> q;
	q.emplace(0LL, root);
	dist[root] = 0;
	while(q.size()) {
		ll cost;
		int now;
		tie(cost, now) = q.top();
		q.pop();
		if(dist[now] != cost) continue;
		for(auto [nxt, ecost] : g[now]) {
			if(chmin(dist[nxt], cost + ecost)) {
				q.emplace(dist[nxt], nxt);
			}
		}
	}
	vector<int> tsort(n);
	iota(all(tsort), 0);
	sort(all(tsort), [&](int i, int j) {
		if(i == j) return false;
		if(i == root) return true;
		if(j == root) return false;
		return dist[i] < dist[j];
	});

	int gsize = n + 2;
	int start = gsize - 2;
	int terminal = gsize - 1;

	MCMF mcf(gsize);

	rep(i, 1, n) {
		debug(i, supply[i]);
		if(supply[i] < 0) {
			int need = -supply[i];
			mcf.addEdge(i, terminal, need, 0LL);
		} else if(supply[i] > 0) {
			int sup = supply[i];
			mcf.addEdge(start, i, sup, 0LL);
		}
	}

	mcf.addEdge(start, 0, INF, 0LL);

	rep(i, n) {
		foa(pr, g[i]) {
			int nxt;
			ll cost;
			tie(nxt, cost) = pr;
			mcf.addEdge(i, nxt, INF, cost);
		}
	}

	auto res = mcf.maxflow(start, terminal);
	debug(res);
	ans += res.second;

	cout << ans << '\n';
}

int main() {
	int n;
	while(cin >> n) solve(n);

	return 0;
}
accuracy: 0.11538461538461539
time_ms: 110
memory_kb: 25432
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=300005;
const ll INF=1LL<<60;
const ll M=1LL<<35;

//最小費用流(DAG)

typedef pair<ll,int> P;

struct edge{int to,cap;ll cost;int rev;};

int V;
vector<edge> G[MAX];
ll h[MAX];
ll dist[MAX];
int prevv[MAX],preve[MAX];
vector<int> id;

void add_edge(int from,int to,int cap,ll cost){
    G[from].push_back((edge){to,cap,cost,int(G[to].size())});
    G[to].push_back((edge){from,0,-cost,int(G[from].size()-1)});
}

ll min_cost_flow(int s,int t,int f){
    ll res=0;
    fill(h,h+V,0);
    for(int v:id){
        for(auto e:G[v]){
            if(e.cap>0) chmin(h[e.to],h[v]+e.cost);
        }
    }
    
    while(f>0){
        priority_queue<P,vector<P>,greater<P>> que;
        fill(dist,dist+V,INF);
        dist[s]=0;
        que.push(P(0,s));
        while(!que.empty()){
            P p=que.top();que.pop();
            int v=p.second;
            if(dist[v]<p.first) continue;
            for(int i=0;i<G[v].size();i++){
                edge &e=G[v][i];
                if(e.cap>0&&dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
                    dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
                    prevv[e.to]=v;
                    preve[e.to]=i;
                    que.push(P(dist[e.to],e.to));
                }
            }
        }
        
        if(dist[t]==INF){
            return -1;
        }
        for(int v=0;v<V;v++){
            h[v]+=dist[v];
        }
        
        if(h[t]==0) break;
        
        int d=f;
        for(int v=t;v!=s;v=prevv[v]){
            d=min(d,G[prevv[v]][preve[v]].cap);
        }
        f-=d;
        res+=d*h[t];
        for(int v=t;v!=s;v=prevv[v]){
            edge &e=G[prevv[v]][preve[v]];
            e.cap-=d;
            G[v][e.rev].cap+=d;
        }
    }
    return res;
}//sからtへの流量fの最小費用流、流せない場合は-1
//idにトポソ順を入れておく

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int N;cin>>N;
    int s=N,t=N+1;
    V=N+2;
    int hen=0;
    for(int i=0;i<N;i++){
        int K;cin>>K;
        hen+=K;
        map<pair<ll,ll>,int> MA;
        map<int,ll> mi;
        for(int j=0;j<K;j++){
            ll a,b;cin>>a>>b;a--;
            MA[mp(a,b)]++;
            if(mi.count(a)) chmin(mi[a],b);
            else mi[a]=b;
        }
        for(auto x:MA){
            add_edge(i,x.fi.fi,x.se,x.fi.se-M);
        }
        for(auto x:mi){
            add_edge(i,x.fi,60000,x.se);
        }
        add_edge(i,t,60000,0);
    }
    add_edge(s,0,60000,0);
    add_edge(s,t,60000,0);
    
    id.push_back(s);
    for(int i=0;i<N;i++) id.push_back(i);
    id.push_back(t);
    
    ll res=min_cost_flow(s,t,60000);
    
    res+=M*hen;
    
    cout<<res<<endl;
}
accuracy: 1
time_ms: 4800
memory_kb: 19176
final_rank: 11

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 20;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

using mP = pair<modint, modint>;
//-----------------------------------
template<typename T>
struct mcf {
private:
	struct edge {
		int to, cap; T cost; int rev;
	};
	vector<vector<edge>> G;
	vector<P> par;
	vector<T> dist;
	T inf = INF/100000;
public:
	mcf(int n) {
		G.resize(n);
		par.resize(n);
		dist.resize(n);
	}
	void add_edge(int from, int to, int cap, T cost) {
		G[from].push_back({ to,cap,cost,(int)G[to].size() });
		G[to].push_back({ from,0,-cost,(int)G[from].size() - 1 });
	}
	pair<T, int> minimum_road(int s, int t) {
		fill(all(par), P{ -1,-1 });
		fill(all(dist), inf);
		dist[s] = 0;
		priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> q;
		q.push({ 0,s });
		while (!q.empty()) {
			pair<T, int> p = q.top(); q.pop();
			int id = p.second;
			if (id == t)continue;
			if (p.first > dist[id])continue;
			rep(j, G[id].size()) {
				if (G[id][j].cap > 0) {
					int to = G[id][j].to;
					T nd = p.first + G[id][j].cost;
					if (nd < dist[to]) {
						dist[to] = nd;
						par[to] = { id,j };
						q.push({ dist[to],to });
					}
				}
			}
		}
		int cur = t;
		int f = mod;
		while (cur != s) {
			int p = par[cur].first, j = par[cur].second;
			if (p < 0)return { -1,-1 };
			f = min(f, G[p][j].cap);
			cur = p;
		}
		cur = t;
		while (cur != s) {
			int p = par[cur].first, j = par[cur].second;
			if (p < 0)return { -1,-1 };
			G[p][j].cap -= f;
			if (G[p][j].rev >= 0) {
				G[cur][G[p][j].rev].cap += f;
			}
			cur = p;
		}
		return { dist[t],f };
	}
	T minimum_cost_flow(int s, int t, int k) {
		T ret = 0;
		rep(i, k) {
			pair<T, int> z = minimum_road(s, t);
			if (z.first < 0)return -1;
			if (k - i <= z.second) {
				ret += z.first * (k - i); break;
			}
			i += z.second - 1;
			ret += z.first * z.second;
		}
		return ret;
	}
};

struct edge {
	int to, cost;
};
void solve() {
	int n; cin >> n;
	vector<vector<edge>> G(n);
	rep(i, n) {
		int k; cin >> k;
		rep(j, k) {
			int to, cost;
			cin >> to >> cost; to--;
			G[i].push_back({ to,cost });
		}
	}
	vector<int> d(2 * n+2);
	mcf<ll> mc(n+2);
	ll ans = 0;
	int ce = 0;
	rep(i, n)for (edge e : G[i]) {
		ce++;
		mc.add_edge(i, e.to, mod, e.cost);
		//mc.add_edge(i, e.to, 1, e.cost-mod);
		ans += e.cost - mod;
		d[i]--;
		d[e.to]++;
		mc.add_edge(e.to, i, 1, mod - e.cost);
	}
	int S = n;
	int T = n+1;
	int sum = 0;
	rep(i, n) {
		if (d[i] > 0) {
			sum += d[i];
			mc.add_edge(S, i, d[i], 0);
		}
		else if (d[i] < 0) {
			mc.add_edge(i, T, -d[i], 0);
		}
	}
	rep1(i, n - 1) {
		mc.add_edge(i, 0, mod, 0);
	}
	ll ad = mc.minimum_cost_flow(S, T, sum);
	ans += ad;
	//cout << ad << "\n";
	ans += ce * mod;
	cout << ans << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(10);
	//init_f();
	//init();
	//while(true)
	//expr();
	//int t; cin >> t; rep(i, t)
	//while(cin>>h>>w,h)
	solve();
	return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 17660
final_rank: 8

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
template <typename T> using posteriority_queue = priority_queue<T, vector<T>, greater<T> >;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
const int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
template <typename T> void unique(vector<T> &a) { a.erase(unique(ALL(a)), a.end()); }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

template <typename T, typename U>
struct PrimalDual {
  using Pui = pair<U, int>;

  struct Edge {
    int dst, rev;
    T cap;
    U cost;
    Edge(int dst, T cap, U cost, int rev) : dst(dst), cap(cap), cost(cost), rev(rev) {}
  };

  vector<vector<Edge> > graph;

  PrimalDual(int n, const T TINF, const U UINF) : n(n), TINF(TINF), UINF(UINF), graph(n), prev_v(n, -1), prev_e(n, -1), potential(n, 0), dist(n) {}

  void add_edge(int src, int dst, T cap, U cost) {
    has_negative_edge |= cost < 0;
    graph[src].emplace_back(dst, cap, cost, graph[dst].size());
    graph[dst].emplace_back(src, 0, -cost, graph[src].size() - 1);
  }

  U minimum_cost_flow(int s, int t, T flow) {
    U res = 0;
    if (has_negative_edge) {
      bellman_ford(s);
      if (dist[t] == UINF) return UINF;
      res += calc(s, t, flow);
    }
    while (flow > 0) {
      dijkstra(s);
      if (dist[t] == UINF) return UINF;
      res += calc(s, t, flow);
    }
    return res;
  }

  U minimum_cost_flow(int s, int t) {
    U res = 0;
    bellman_ford(s);
    if (potential[t] >= 0 || dist[t] == UINF) return res;
    T tmp = TINF;
    res += calc(s, t, tmp);
    while (true) {
      dijkstra(s);
      if (potential[t] >= 0 || dist[t] == UINF) return res;
      res += calc(s, t, tmp);
    }
  }

  pair<T, U> min_cost_max_flow(int s, int t, T flow) {
    T mx = flow;
    U cost = 0;
    if (has_negative_edge) {
      bellman_ford(s);
      if (dist[t] == UINF) return {mx - flow, cost};
      cost += calc(s, t, flow);
    }
    while (flow > 0) {
      dijkstra(s);
      if (dist[t] == UINF) return {mx - flow, cost};
      cost += calc(s, t, flow);
    }
    return {mx - flow, cost};
  }

private:
  int n;
  const T TINF;
  const U UINF;
  bool has_negative_edge = false;
  vector<int> prev_v, prev_e;
  vector<U> potential, dist;
  priority_queue<Pui, vector<Pui>, greater<Pui> > que;

  void bellman_ford(int s) {
    fill(ALL(dist), UINF);
    dist[s] = 0;
    bool is_updated = true;
    REP(step, n) {
      is_updated = false;
      REP(i, n) if (dist[i] != UINF) {
        REP(j, graph[i].size()) {
          Edge e = graph[i][j];
          if (e.cap > 0 && dist[e.dst] > dist[i] + e.cost) {
            dist[e.dst] = dist[i] + e.cost;
            prev_v[e.dst] = i;
            prev_e[e.dst] = j;
            is_updated = true;
          }
        }
      }
      if (!is_updated) break;
    }
    assert(!is_updated);
    REP(i, n) {
      if (dist[i] != UINF) potential[i] += dist[i];
    }
  }

  void dijkstra(int s) {
    fill(ALL(dist), UINF);
    dist[s] = 0;
    que.emplace(0, s);
    while (!que.empty()) {
      Pui pr = que.top(); que.pop();
      int ver = pr.second;
      if (dist[ver] < pr.first) continue;
      REP(i, graph[ver].size()) {
        Edge e = graph[ver][i];
        U nx = dist[ver] + e.cost + potential[ver] - potential[e.dst];
        if (e.cap > 0 && dist[e.dst] > nx) {
          dist[e.dst] = nx;
          prev_v[e.dst] = ver;
          prev_e[e.dst] = i;
          que.emplace(dist[e.dst], e.dst);
        }
      }
    }
    REP(i, n) {
      if (dist[i] != UINF) potential[i] += dist[i];
    }
  }

  U calc(int s, int t, T &flow) {
    T f = flow;
    for (int v = t; v != s; v = prev_v[v]) f = min(f, graph[prev_v[v]][prev_e[v]].cap);
    flow -= f;
    for (int v = t; v != s; v = prev_v[v]) {
      Edge &e = graph[prev_v[v]][prev_e[v]];
      e.cap -= f;
      graph[v][e.rev].cap += f;
    }
    return potential[t] * f;
  }
};

int main() {
  int n; cin >> n;
  ll ans = 0;
  PrimalDual<int, ll> pd(n + 2, INF, LINF);
  vector<int> cnt(n, 0);
  REP(i, n) {
    int k; cin >> k;
    cnt[i] += k;
    while (k--) {
      int t, c; cin >> t >> c; --t;
      ans += c;
      pd.add_edge(i, t, INF, c);
      --cnt[t];
    }
  }
  cnt[0] = -INF;
  int S = n, T = n + 1, f = 0;
  REP(i, n) {
    if (cnt[i] > 0) {
      pd.add_edge(i, T, cnt[i], 0);
      f += cnt[i];
    } else if (cnt[i] < 0) {
      pd.add_edge(S, i, -cnt[i], 0);
    }
  }
  cout << ans + pd.minimum_cost_flow(S, T, f) << '\n';
  return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 6004
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define MAX 2001
#define inf 1<<29
#define linf (1e16)
#define eps (1e-8)
#define Eps (1e-12)
#define mod 1000000007
#define pi acos(-1.0)
#define phi (1.0+sqrt(5.0))/2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define pld(a) printf("%.10Lf\n",(ld)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;
typedef vector<int> vi;
typedef vector<pii> vpi;

struct edge{ ll to,cap,cost,rev; };

int v;
vector<edge> e[MAX];
ll h[MAX];
ll dist[MAX];
ll prevv[MAX],preve[MAX];

void add_edge(int from,int to,ll cap,ll cost){
  e[from].push_back((edge){to,cap,cost,(ll)e[to].size()});
  e[to].push_back((edge){from,0,-cost,(ll)e[from].size()-1});
}
 
ll min_cost_flow(ll s,ll t,ll f){
  ll res=0;
  fill(h,h+v,0);
  fill(prevv,prevv+MAX,0);
  fill(preve,preve+MAX,0);
  while(f>0){
    priority_queue<pll,vector<pll>,greater<pll> > pq;
    fill(dist,dist+v,linf);
    dist[s]=0;
    pq.push(pll(0,s));
    while(pq.size()){
      pll p=pq.top();
      pq.pop();
      int u=p.second;
      if(dist[u]<p.first)continue;
      for(int i=0;i<e[u].size();i++){
        edge &E=e[u][i];
        if(E.cap>0 && dist[E.to]>dist[u]+E.cost+h[u]-h[E.to]){
          dist[E.to]=dist[u]+E.cost+h[u]-h[E.to];
          prevv[E.to]=u;
          preve[E.to]=i;
          pq.push(pll(dist[E.to],E.to));
        }
      }
    }
    if(dist[t]==linf)return -1;
    for(int i=0;i<v;i++)h[i]+=dist[i];
 
    ll d=f;
    for(int u=t;u!=s;u=prevv[u]){
      d=min(d,e[prevv[u]][preve[u]].cap);
    }
    f-=d;
    res+=d*h[t];
    for(int u=t;u!=s;u=prevv[u]){
      edge &E=e[prevv[u]][preve[u]];
      E.cap-=d;
      e[u][E.rev].cap+=d;
    }
  }
  return res;
}


ll n,k,flow=0;
vector<pii> E[MAX];
ll ind[MAX],outd[MAX];
ll cost[MAX][MAX];

void dijkstra(int root){
  priority_queue<pll,vector<pll>,greater<pll> > pq;
  cost[root][root]=0;
  pq.push(mp(0,root));

  while(pq.size()){
    pll u=pq.top();
    pq.pop();

    if(cost[root][u.s]<u.f)continue;

    FOR(i,0,E[u.s].size()){
      int next=E[u.s][i].f;
      ll c = cost[root][u.s]+E[u.s][i].s;
      if(c<cost[root][next]){
        cost[root][next]=c;
        pq.push(mp(c,next));
      }
    }
  }
}

ll solve(){
  ll ans = 0;
  fill(ind,ind+MAX,0);
  fill(outd,outd+MAX,0);
  FOR(i,0,MAX)fill(cost[i],cost[i]+MAX,inf);
  FOR(i,0,n){
    outd[i] = E[i].size();
    FOR(j,0,E[i].size()){
      ind[E[i][j].f]++;
      ans+=E[i][j].s;
    }
  }
  FOR(i,0,n)dijkstra(i);
  vector<pii> L,R;
  FOR(i,1,n){
    if(outd[i]==0)continue;
    if(outd[i]<ind[i])L.pb(mp(i,ind[i]-outd[i]));
    if(ind[i]<outd[i]){
      R.pb(mp(i,outd[i]-ind[i]));
      flow+=(outd[i]-ind[i]);
    }
  }
  int s=L.size()+R.size(),t=s+1,u=t+1;
  v = u+1;
  FOR(i,0,L.size()){
    FOR(j,0,R.size()){
      int a = L[i].f, b = R[j].f;
      if(cost[a][b]==inf)continue;
      add_edge(i,j+L.size(),R[j].s,cost[a][b]);
    }
  }
  FOR(i,0,L.size())add_edge(s,i,L[i].s,0);
  FOR(i,0,R.size())add_edge(i+L.size(),t,R[i].s,0);
  add_edge(s,u,inf,0);
  FOR(i,0,R.size())add_edge(u,i+L.size(),R[i].s,cost[0][R[i].f]);
  ll res = min_cost_flow(s,t,flow);
  return ans+res;
}

int main()
{
  cin>>n;
  FOR(i,0,n){
    cin>>k;
    FOR(j,0,k){
      ll a,b;
      cin>>a>>b;
      E[i].pb(mp(a-1,b));
    }
  }
  cout<<solve()<<endl;
  return 0;
}
accuracy: 1
time_ms: 4880
memory_kb: 47376
final_rank: 12

code_snippet: #include<bits/stdc++.h>
#define MAX 2001
#define inf 1<<29
#define linf (1e16)
#define eps (1e-8)
#define Eps (1e-12)
#define mod 1000000007
#define pi acos(-1.0)
#define phi (1.0+sqrt(5.0))/2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define pld(a) printf("%.10Lf\n",(ld)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;
typedef vector<int> vi;
typedef vector<pii> vpi;

struct edge{ int to,cap,cost,rev; };

int v;
vector<edge> e[MAX];
int h[MAX];
int dist[MAX];
int prevv[MAX],preve[MAX];

void add_edge(int from,int to,int cap,int cost){
  e[from].push_back((edge){to,cap,cost,(int)e[to].size()});
  e[to].push_back((edge){from,0,-cost,(int)e[from].size()-1});
}
 
int min_cost_flow(int s,int t,int f){
  int res=0;
  fill(h,h+v,0);
  fill(prevv,prevv+MAX,0);
  fill(preve,preve+MAX,0);
  while(f>0){
    priority_queue<pii,vector<pii>,greater<pii> > pq;
    fill(dist,dist+v,inf);
    dist[s]=0;
    pq.push(pii(0,s));
    while(pq.size()){
      pii p=pq.top();
      pq.pop();
      int u=p.second;
      if(dist[u]<p.first)continue;
      for(int i=0;i<e[u].size();i++){
        edge &E=e[u][i];
        if(E.cap>0 && dist[E.to]>dist[u]+E.cost+h[u]-h[E.to]){
          dist[E.to]=dist[u]+E.cost+h[u]-h[E.to];
          prevv[E.to]=u;
          preve[E.to]=i;
          pq.push(pii(dist[E.to],E.to));
        }
      }
    }
    if(dist[t]==inf)return -1;
    for(int i=0;i<v;i++)h[i]+=dist[i];
 
    int d=f;
    for(int u=t;u!=s;u=prevv[u]){
      d=min(d,e[prevv[u]][preve[u]].cap);
    }
    f-=d;
    res+=d*h[t];
    for(int u=t;u!=s;u=prevv[u]){
      edge &E=e[prevv[u]][preve[u]];
      E.cap-=d;
      e[u][E.rev].cap+=d;
    }
  }
  return res;
}


int n,k,flow=0;
vector<pii> E[MAX];
int ind[MAX],outd[MAX];
int cost[MAX][MAX];

void dijkstra(int root){
  priority_queue<pii,vector<pii>,greater<pii> > pq;
  cost[root][root]=0;
  pq.push(mp(0,root));

  while(pq.size()){
    pii u=pq.top();
    pq.pop();

    if(cost[root][u.s]<u.f)continue;

    FOR(i,0,E[u.s].size()){
      int next=E[u.s][i].f;
      int c = cost[root][u.s]+E[u.s][i].s;
      if(c<cost[root][next]){
        cost[root][next]=c;
        pq.push(mp(c,next));
      }
    }
  }
}

int solve(){
  int ans = 0;
  fill(ind,ind+MAX,0);
  fill(outd,outd+MAX,0);
  FOR(i,0,MAX)fill(cost[i],cost[i]+MAX,inf);
  FOR(i,0,n){
    outd[i] = E[i].size();
    FOR(j,0,E[i].size()){
      ind[E[i][j].f]++;
      ans+=E[i][j].s;
    }
  }
  FOR(i,0,n)dijkstra(i);
  vector<pii> L,R;
  FOR(i,1,n){
    if(outd[i]==0)continue;
    if(outd[i]<ind[i])L.pb(mp(i,ind[i]-outd[i]));
    if(ind[i]<outd[i]){
      R.pb(mp(i,outd[i]-ind[i]));
      flow+=(outd[i]-ind[i]);
    }
  }
  int s=L.size()+R.size(),t=s+1,u=t+1;
  v = u+1;
  FOR(i,0,L.size()){
    FOR(j,0,R.size()){
      int a = L[i].f, b = R[j].f;
      if(cost[a][b]==inf)continue;
      add_edge(i,j+L.size(),R[j].s,cost[a][b]);
    }
  }
  FOR(i,0,L.size())add_edge(s,i,L[i].s,0);
  FOR(i,0,R.size())add_edge(i+L.size(),t,R[i].s,0);
  add_edge(s,u,inf,0);
  FOR(i,0,R.size())add_edge(u,i+L.size(),R[i].s,cost[0][R[i].f]);
  int res = min_cost_flow(s,t,flow);
  return ans+res;
}

int main()
{
  cin>>n;
  FOR(i,0,n){
    cin>>k;
    FOR(j,0,k){
      int a,b;
      cin>>a>>b;
      E[i].pb(mp(a-1,b));
    }
  }
  cout<<solve()<<endl;
  return 0;
}
accuracy: 0.9807692307692307
time_ms: 4560
memory_kb: 25440
final_rank: 14

code_snippet: #include<bits/stdc++.h>
#define MAX 1001
#define inf 1<<29
#define linf (1e16)
#define eps (1e-8)
#define Eps (1e-12)
#define mod 1000000007
#define pi acos(-1.0)
#define phi (1.0+sqrt(5.0))/2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define pld(a) printf("%.10Lf\n",(ld)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;
typedef vector<int> vi;
typedef vector<pii> vpi;

struct edge{ int to,cap,cost,rev; };

int v;
vector<edge> e[MAX];
int h[MAX];
int dist[MAX];
int prevv[MAX],preve[MAX];

void add_edge(int from,int to,int cap,int cost){
  e[from].push_back((edge){to,cap,cost,(int)e[to].size()});
  e[to].push_back((edge){from,0,-cost,(int)e[from].size()-1});
}
 
int min_cost_flow(int s,int t,int f){
  int res=0;
  fill(h,h+v,0);
  fill(prevv,prevv+MAX,0);
  fill(preve,preve+MAX,0);
  while(f>0){
    priority_queue<pii,vector<pii>,greater<pii> > pq;
    fill(dist,dist+v,inf);
    dist[s]=0;
    pq.push(pii(0,s));
    while(pq.size()){
      pii p=pq.top();
      pq.pop();
      int u=p.second;
      if(dist[u]<p.first)continue;
      for(int i=0;i<e[u].size();i++){
        edge &E=e[u][i];
        if(E.cap>0 && dist[E.to]>dist[u]+E.cost+h[u]-h[E.to]){
          dist[E.to]=dist[u]+E.cost+h[u]-h[E.to];
          prevv[E.to]=u;
          preve[E.to]=i;
          pq.push(pii(dist[E.to],E.to));
        }
      }
    }
    if(dist[t]==inf)return -1;
    for(int i=0;i<v;i++)h[i]+=dist[i];
 
    int d=f;
    for(int u=t;u!=s;u=prevv[u]){
      d=min(d,e[prevv[u]][preve[u]].cap);
    }
    f-=d;
    res+=d*h[t];
    for(int u=t;u!=s;u=prevv[u]){
      edge &E=e[prevv[u]][preve[u]];
      E.cap-=d;
      e[u][E.rev].cap+=d;
    }
  }
  return res;
}


int n,k,flow=0;
vector<pii> E[MAX];
int ind[MAX],outd[MAX];
int cost[MAX][MAX];

void dijkstra(int root){
  priority_queue<pii,vector<pii>,greater<pii> > pq;
  cost[root][root]=0;
  pq.push(mp(0,root));

  while(pq.size()){
    pii u=pq.top();
    pq.pop();

    if(cost[root][u.s]<u.f)continue;

    FOR(i,0,E[u.s].size()){
      int next=E[u.s][i].f;
      int c = cost[root][u.s]+E[u.s][i].s;
      if(c<cost[root][next]){
        cost[root][next]=c;
        pq.push(mp(c,next));
      }
    }
  }
}

int solve(){
  int ans = 0;
  fill(ind,ind+MAX,0);
  fill(outd,outd+MAX,0);
  FOR(i,0,MAX)fill(cost[i],cost[i]+MAX,inf);
  FOR(i,0,n){
    outd[i] = E[i].size();
    FOR(j,0,E[i].size()){
      ind[E[i][j].f]++;
      ans+=E[i][j].s;
    }
  }
  FOR(i,0,n)dijkstra(i);
  vector<pii> L,R;
  FOR(i,1,n){
    if(outd[i]==0)continue;
    if(outd[i]<ind[i])L.pb(mp(i,ind[i]-outd[i]));
    if(ind[i]<outd[i]){
      R.pb(mp(i,outd[i]-ind[i]));
      flow+=outd[i]-ind[i];
    }
  }
  int s=L.size()+R.size(),t=s+1,u=t+1;
  v = u+1;
  FOR(i,0,L.size()){
    FOR(j,0,R.size()){
      int a = L[i].f, b = R[j].f;
      if(cost[a][b]==inf)continue;
      add_edge(i,j+L.size(),inf,cost[a][b]);
    }
  }
  FOR(i,0,L.size())add_edge(s,i,L[i].s,0);
  FOR(i,0,R.size())add_edge(i+L.size(),t,R[i].s,0);
  add_edge(s,u,R.size(),0);
  FOR(i,0,R.size())add_edge(u,i+L.size(),inf,cost[0][R[i].f]);
  int res = min_cost_flow(s,t,flow);
  return ans+res;
}

int main()
{
  cin>>n;
  FOR(i,0,n){
    cin>>k;
    FOR(j,0,k){
      int a,b;
      cin>>a>>b;
      E[i].pb(mp(a-1,b));
    }
  }
  cout<<solve()<<endl;
  return 0;
}
accuracy: 0.1346153846153846
time_ms: 4600
memory_kb: 13724
final_rank: 16

code_snippet: #include<bits/stdc++.h>
#define MAX 1001
#define inf 1<<29
#define linf (1e16)
#define eps (1e-8)
#define Eps (1e-12)
#define mod 1000000007
#define pi acos(-1.0)
#define phi (1.0+sqrt(5.0))/2.0
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define pd(a) printf("%.10f\n",(double)(a))
#define pld(a) printf("%.10Lf\n",(ld)(a))
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define RFOR(i,a,b) for(int i=(a)-1;(b)<=i;i--)
#define Unique(v) v.erase(unique(all(v)),v.end())
#define equals(a,b) (fabs((a)-(b))<eps)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,double> pid;
typedef pair<double,int> pdi;
typedef pair<double,double> pdd;
typedef vector<int> vi;
typedef vector<pii> vpi;

struct edge{ int to,cap,cost,rev; };

int v;
vector<edge> e[MAX];
int h[MAX];
int dist[MAX];
int prevv[MAX],preve[MAX];

void add_edge(int from,int to,int cap,int cost){
  e[from].push_back((edge){to,cap,cost,(int)e[to].size()});
  e[to].push_back((edge){from,0,-cost,(int)e[from].size()-1});
}
 
int min_cost_flow(int s,int t,int f){
  int res=0;
  fill(h,h+v,0);
  fill(prevv,prevv+MAX,0);
  fill(preve,preve+MAX,0);
  while(f>0){
    priority_queue<pii,vector<pii>,greater<pii> > pq;
    fill(dist,dist+v,inf);
    dist[s]=0;
    pq.push(pii(0,s));
    while(pq.size()){
      pii p=pq.top();
      pq.pop();
      int u=p.second;
      if(dist[u]<p.first)continue;
      for(int i=0;i<e[u].size();i++){
        edge &E=e[u][i];
        if(E.cap>0 && dist[E.to]>dist[u]+E.cost+h[u]-h[E.to]){
          dist[E.to]=dist[u]+E.cost+h[u]-h[E.to];
          prevv[E.to]=u;
          preve[E.to]=i;
          pq.push(pii(dist[E.to],E.to));
        }
      }
    }
    if(dist[t]==inf)return -1;
    for(int i=0;i<v;i++)h[i]+=dist[i];
 
    int d=f;
    for(int u=t;u!=s;u=prevv[u]){
      d=min(d,e[prevv[u]][preve[u]].cap);
    }
    f-=d;
    res+=d*h[t];
    for(int u=t;u!=s;u=prevv[u]){
      edge &E=e[prevv[u]][preve[u]];
      E.cap-=d;
      e[u][E.rev].cap+=d;
    }
  }
  return res;
}


int n,k,flow=0;
vector<pii> E[MAX];
int ind[MAX],outd[MAX];
int cost[MAX][MAX];

void dijkstra(int root){
  priority_queue<pii,vector<pii>,greater<pii> > pq;
  cost[root][root]=0;
  pq.push(mp(0,root));

  while(pq.size()){
    pii u=pq.top();
    pq.pop();

    if(cost[root][u.s]<u.f)continue;

    FOR(i,0,E[u.s].size()){
      int next=E[u.s][i].f;
      int c = cost[root][u.s]+E[u.s][i].s;
      if(c<cost[root][next]){
        cost[root][next]=c;
        pq.push(mp(c,next));
      }
    }
  }
}

int solve(){
  int ans = 0;
  fill(ind,ind+MAX,0);
  fill(outd,outd+MAX,0);
  FOR(i,0,MAX)fill(cost[i],cost[i]+MAX,inf);
  FOR(i,0,n){
    outd[i] = E[i].size();
    FOR(j,0,E[i].size()){
      ind[E[i][j].f]++;
      ans+=E[i][j].s;
    }
  }
  FOR(i,0,n)dijkstra(i);
  vector<pii> L,R;
  FOR(i,1,n){
    if(outd[i]==0)continue;
    if(outd[i]<ind[i])L.pb(mp(i,ind[i]-outd[i]));
    if(ind[i]<outd[i]){
      R.pb(mp(i,outd[i]-ind[i]));
      flow+=outd[i]-ind[i];
    }
  }
  int s=L.size()+R.size(),t=s+1,u=t+1;
  v = u+1;
  FOR(i,0,L.size()){
    FOR(j,0,R.size()){
      int a = L[i].f, b = R[j].f;
      if(cost[a][b]==inf)continue;
      add_edge(i,j+L.size(),L[i].s,cost[a][b]);
    }
  }
  FOR(i,0,L.size())add_edge(s,i,L[i].s,0);
  FOR(i,0,R.size())add_edge(i+L.size(),t,R[i].s,0);
  add_edge(s,u,R.size(),0);
  FOR(i,0,R.size())add_edge(u,i+L.size(),R[i].s,cost[0][R[i].f]);
  int res = min_cost_flow(s,t,flow);
  return ans+res;
}

int main()
{
  cin>>n;
  FOR(i,0,n){
    cin>>k;
    FOR(j,0,k){
      int a,b;
      cin>>a>>b;
      E[i].pb(mp(a-1,b));
    }
  }
  cout<<solve()<<endl;
  return 0;
}
accuracy: 0.1346153846153846
time_ms: 4590
memory_kb: 13728
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


template<typename TF,typename TC>
struct PrimalDual{
  struct edge{
    int to;
    TF cap;
    TC cost;
    int rev;
    edge(){}
    edge(int to,TF cap,TC cost,int rev):to(to),cap(cap),cost(cost),rev(rev){}
  };

  static const TC INF;
  vector<vector<edge>> G;
  vector<TC> h,dist;
  vector<int> prevv,preve;

  PrimalDual(){}
  PrimalDual(int n):G(n),h(n),dist(n),prevv(n),preve(n){}

  void add_edge(int u,int v,TF cap,TC cost){
    G[u].emplace_back(v,cap,cost,G[v].size());
    G[v].emplace_back(u,0,-cost,G[u].size()-1);
  }

  void dijkstra(int s){
    struct P{
      TC first;
      int second;
      P(TC first,int second):first(first),second(second){}
      bool operator<(const P&a) const{return a.first<first;}
    };
    priority_queue<P> que;
    fill(dist.begin(),dist.end(),INF);

    dist[s]=0;
    que.emplace(dist[s],s);
    while(!que.empty()){
      P p=que.top();que.pop();
      int v=p.second;
      if(dist[v]<p.first) continue;
      for(int i=0;i<(int)G[v].size();i++){
        edge &e=G[v][i];
        if(e.cap==0) continue;
        if(dist[v]+e.cost+h[v]-h[e.to]<dist[e.to]){
          dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
          prevv[e.to]=v;
          preve[e.to]=i;
          que.emplace(dist[e.to],e.to);
        }
      }
    }
  }

  TC flow(int s,int t,TF f,int &ok){
    TC res=0;
    fill(h.begin(),h.end(),0);
    while(f>0){
      dijkstra(s);
      if(dist[t]==INF){
        ok=0;
        return res;
      }

      for(int v=0;v<(int)h.size();v++)
        if(dist[v]<INF) h[v]=h[v]+dist[v];

      TF d=f;
      for(int v=t;v!=s;v=prevv[v])
        d=min(d,G[prevv[v]][preve[v]].cap);

      f-=d;
      res=res+h[t]*d;
      for(int v=t;v!=s;v=prevv[v]){
        edge &e=G[prevv[v]][preve[v]];
        e.cap-=d;
        G[v][e.rev].cap+=d;
      }
    }
    ok=1;
    return res;
  }
};
template<typename TF, typename TC> const TC PrimalDual<TF, TC>::INF = numeric_limits<TC>::max()/2;

//BEGIN CUT HERE
template<typename TF,typename TC>
struct NegativeEdge{
  PrimalDual<TF, TC> G;
  vector<TF> fs;
  TC sum;
  int S,T;
  NegativeEdge(){}
  NegativeEdge(int n):G(n+2),fs(n+2,0),sum(0),S(n),T(n+1){}

  void use_edge(int u,int v,TF cap,TC cost){
    fs[u]-=cap;
    fs[v]+=cap;
    sum=sum+cost*cap;
  }

  void add_edge(int u,int v,TF cap,TC cost){
    if(cost<TC(0)){
      use_edge(u,v,cap,cost);
      swap(u,v);
      cost=-cost;
    }
    G.add_edge(u,v,cap,cost);
  }

  TC flow(int ts,int tt,TF tf,int &ok){
    fs[ts]+=tf;
    fs[tt]-=tf;

    TF f=0;
    for(int i=0;i<S;i++){
      if(fs[i]>0){
        f+=fs[i];
        G.add_edge(S,i,+fs[i],TC(0));
      }
      if(fs[i]<0){
        G.add_edge(i,T,-fs[i],TC(0));
      }
    }
    return sum+G.flow(S,T,f,ok);
  }
};
//END CUT HERE

//INSERT ABOVE HERE
signed CFR190_B(){
  using ll = long long;
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m;
  cin>>n>>m;
  vector<string> vp(n);
  vector<int> vs(n);
  for(int i=0;i<n;i++) cin>>vp[i]>>vs[i];
  vector<int> ss(m);
  for(int i=0;i<m;i++) cin>>ss[i];

  int S=n+m,T=n+m+1;
  NegativeEdge<ll, ll> G(n+m+2);

  for(int i=0;i<m;i++){
    G.add_edge(S,i,1,0);
    for(int j=0;j<n;j++){
      if(vp[j]=="ATK"){
        if(ss[i]>=vs[j]) G.add_edge(i,m+j,1,vs[j]-ss[i]);
      }
      if(vp[j]=="DEF"){
        if(ss[i]> vs[j]) G.add_edge(i,m+j,1,0);
      }
    }
  }

  auto H=G;
  for(int i=0;i<m;i++){
    G.add_edge(i,T,1,-ss[i]);
    H.add_edge(i,T,1,0);
  }

  for(int j=0;j<n;j++){
    G.use_edge(m+j,T,1,0);
    H.add_edge(m+j,T,1,0);
  }

  int ok;
  ll ans=0;
  if(n<m){
    ll gv=G.flow(S,T,m,ok);
    if(ok) chmin(ans,gv);
  }
  ll hv=H.flow(S,T,m,ok);
  if(ok) chmin(ans,hv);

  cout<<-ans<<endl;
  return 0;
}
/*
  verified on 2019/07/05
  https://codeforces.com/contest/321/problem/B
*/

signed AOJ_2627(){
  using ll = long long;
  const ll INF = 1e9;
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin>>n;
  NegativeEdge<int, ll> G(n+1);

  for(int i=0;i<n;i++){
    int k;
    cin>>k;
    map<int, int> dst;
    for(int j=0;j<k;j++){
      int t,c;
      cin>>t>>c;
      t--;
      G.use_edge(i,t,1,c);
      if(!dst.count(t)) dst[t]=c;
      chmin(dst[t],c);
    }

    for(auto p:dst)
      G.add_edge(i,p.first,INF,p.second);

    G.add_edge(i,n,INF,0);
  }

  int ok;
  ll ans=G.flow(0,n,INF,ok);
  assert(ok);
  cout<<ans<<endl;
  return 0;
}
/*
  verified on 2019/07/05
  http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2627
*/

const int MAX = 52;
struct ARR{
  array<int, MAX> val;
  ARR(){fill(val.begin(),val.end(),0);}
  ARR(int x){fill(val.begin(),val.end(),x);}
  int& operator[](int k){return val[k];};
  int operator[](int k)const{return val[k];};
  ARR operator+(const ARR &oth) const{
    ARR res;
    for(int i=0;i<MAX;i++)
      res[i]=val[i]+oth[i];
    return res;
  }
  ARR operator-(const ARR &oth) const{
    ARR res;
    for(int i=0;i<MAX;i++)
      res[i]=val[i]-oth[i];
    return res;
  }
  ARR operator-() const{
    ARR res;
    for(int i=0;i<MAX;i++)
      res[i]=-val[i];
    return res;
  }
  ARR operator*(const int &k) const{
    ARR res;
    for(int i=0;i<MAX;i++)
      res[i]=val[i]*k;
    return res;
  }
  ARR operator/(const int &k) const{
    ARR res;
    for(int i=0;i<MAX;i++)
      res[i]=val[i]/k;
    return res;
  }
  bool operator< (const ARR &oth) const{
    return val< oth.val;
  }
  bool operator==(const ARR &oth) const{
    return val==oth.val;
  }
};

namespace std {
  template<> class numeric_limits<ARR> {
  public:
    static ARR max() {return ARR(numeric_limits<int>::max());};
  };
}

signed AOJ_2679(){
  int n;
  cin>>n;
  vector<string> vs(n);
  for(int i=0;i<n;i++) cin>>vs[i];

  auto enc=
    [&](char c){
      if(isupper(c)) return c-'A';
      return 26+c-'a';
    };
  auto dec=
    [&](int d){
      if(d<26) return 'A'+d;
      return 'a'+d-26;
    };

  int S=n*2,T=n*2+1;
  NegativeEdge<int, ARR> G(n*2+2);
  for(int i=0;i<n;i++){
    G.add_edge(S,i,1,ARR());
    G.add_edge(n+i,T,1,ARR());
  }

  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      ARR cost;
      cost[enc(vs[i][j])]=-1;
      G.add_edge(i,n+j,1,cost);
    }
  }

  int ok;
  auto res=G.flow(S,T,n,ok);
  assert(ok);

  string ans;
  for(int i=0;i<MAX;i++)
    for(int j=0;j<-res[i];j++)
      ans+=dec(i);
  cout<<ans<<endl;

  return 0;
}
/*
  verified on 2019/07/05
  http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2679
*/


signed main(){
  //CFR190_B();
  AOJ_2627();
  //AOJ_2679();
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 4800
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


template<typename TF,typename TC>
struct PrimalDual{
  struct edge{
    int to;
    TF cap;
    TC cost;
    int rev;
    edge(){}
    edge(int to,TF cap,TC cost,int rev):to(to),cap(cap),cost(cost),rev(rev){}
  };

  static constexpr TC INF = numeric_limits<TC>::max()/2;
  vector<vector<edge>> G;
  vector<TC> h,dist;
  vector<int> prevv,preve;

  PrimalDual(){}
  PrimalDual(int n):G(n),h(n),dist(n),prevv(n),preve(n){}

  void add_edge(int u,int v,TF cap,TC cost){
    G[u].emplace_back(v,cap,cost,G[v].size());
    G[v].emplace_back(u,0,-cost,G[u].size()-1);
  }

  void dijkstra(int s){
    struct P{
      TC first;
      int second;
      P(TC first,int second):first(first),second(second){}
      bool operator<(const P&a) const{return first>a.first;}
    };
    priority_queue<P> que;
    fill(dist.begin(),dist.end(),INF);

    dist[s]=0;
    que.emplace(dist[s],s);
    while(!que.empty()){
      P p=que.top();que.pop();
      int v=p.second;
      if(dist[v]<p.first) continue;
      for(int i=0;i<(int)G[v].size();i++){
        edge &e=G[v][i];
        if(e.cap==0) continue;
        if(dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
          dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
          prevv[e.to]=v;
          preve[e.to]=i;
          que.emplace(dist[e.to],e.to);
        }
      }
    }
  }

  TC flow(int s,int t,TF f,int &ok){
    TC res=0;
    fill(h.begin(),h.end(),0);
    while(f>0){
      dijkstra(s);
      if(dist[t]==INF) return ok=0;

      for(int v=0;v<(int)h.size();v++)
        if(dist[v]<INF) h[v]+=dist[v];

      TF d=f;
      for(int v=t;v!=s;v=prevv[v])
        d=min(d,G[prevv[v]][preve[v]].cap);

      f-=d;
      res+=d*h[t];
      for(int v=t;v!=s;v=prevv[v]){
        edge &e=G[prevv[v]][preve[v]];
        e.cap-=d;
        G[v][e.rev].cap+=d;
      }
    }
    ok=1;
    return res;
  }
};
template<typename TF, typename TC> constexpr TC PrimalDual<TF, TC>::INF;

//BEGIN CUT HERE
template<typename TF,typename TC>
struct NegativeEdge{
  PrimalDual<TF, TC> G;
  vector<TF> fs;
  TC sum;
  int S,T;
  NegativeEdge(){}
  NegativeEdge(int n):G(n+2),fs(n+2,0),sum(0),S(n),T(n+1){}

  void use_edge(int u,int v,TF cap,TC cost){
    fs[u]-=cap;
    fs[v]+=cap;
    sum+=cap*cost;
  }

  void add_edge(int u,int v,TF cap,TC cost){
    if(cost<0){
      use_edge(u,v,cap,cost);
      swap(u,v);
      cost=-cost;
    }
    G.add_edge(u,v,cap,cost);
  }

  TC flow(int ts,int tt,TF tf,int &ok){
    fs[ts]+=tf;
    fs[tt]-=tf;

    TF f=0;
    for(int i=0;i<S;i++){
      if(fs[i]>0){
        f+=fs[i];
        G.add_edge(S,i,+fs[i],TC(0));
      }
      if(fs[i]<0){
        G.add_edge(i,T,-fs[i],TC(0));
      }
    }
    return sum+G.flow(S,T,f,ok);
  }
};
//END CUT HERE

//INSERT ABOVE HERE
signed CFR190_B(){
  using ll = long long;
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,m;
  cin>>n>>m;
  vector<string> vp(n);
  vector<int> vs(n);
  for(int i=0;i<n;i++) cin>>vp[i]>>vs[i];
  vector<int> ss(m);
  for(int i=0;i<m;i++) cin>>ss[i];

  int S=n+m,T=n+m+1;
  NegativeEdge<ll, ll> G(n+m+2);

  for(int i=0;i<m;i++){
    G.add_edge(S,i,1,0);
    for(int j=0;j<n;j++){
      if(vp[j]=="ATK"){
        if(ss[i]>=vs[j]) G.add_edge(i,m+j,1,vs[j]-ss[i]);
      }
      if(vp[j]=="DEF"){
        if(ss[i]> vs[j]) G.add_edge(i,m+j,1,0);
      }
    }
  }

  auto H=G;
  for(int i=0;i<m;i++){
    G.add_edge(i,T,1,-ss[i]);
    H.add_edge(i,T,1,0);
  }

  for(int j=0;j<n;j++){
    G.use_edge(m+j,T,1,0);
    H.add_edge(m+j,T,1,0);
  }

  int ok;
  ll ans=0;

  ll gv=G.flow(S,T,m,ok);
  if(ok) chmin(ans,gv);
  ll hv=H.flow(S,T,m,ok);
  if(ok) chmin(ans,hv);

  cout<<-ans<<endl;
  return 0;
}
/*
  verified on 2019/06/20
  https://codeforces.com/contest/321/problem/B
*/

signed AOJ_2627(){
  using ll = long long;
  const ll INF = 1e9;
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin>>n;
  NegativeEdge<int, ll> G(n+1);

  for(int i=0;i<n;i++){
    int k;
    cin>>k;
    map<int, int> dst;
    for(int j=0;j<k;j++){
      int t,c;
      cin>>t>>c;
      t--;
      G.use_edge(i,t,1,c);
      if(!dst.count(t)) dst[t]=c;
      chmin(dst[t],c);
    }

    for(auto p:dst)
      G.add_edge(i,p.first,INF,p.second);

    G.add_edge(i,n,INF,0);
  }

  int ok;
  ll ans=G.flow(0,n,INF,ok);
  assert(ok);
  cout<<ans<<endl;
  return 0;
}
/*
  verified on 2019/07/05
  http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2627
*/

signed main(){
  //CFR190_B();
  AOJ_2627();
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 4828
final_rank: 2

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

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b)a=b;};


template<typename TF,typename TC>
struct PrimalDual{
  struct edge{
    Int to;
    TF cap;
    TC cost;
    Int rev;
    edge(){}
    edge(Int to,TF cap,TC cost,Int rev):to(to),cap(cap),cost(cost),rev(rev){}
  };

  static constexpr TC INF = numeric_limits<TC>::max()/2;
  vector<vector<edge>> G;
  vector<TC> h,dist;
  vector<Int> prevv,preve;

  PrimalDual(){}
  PrimalDual(Int n):G(n),h(n),dist(n),prevv(n),preve(n){}

  void add_edge(Int u,Int v,TF cap,TC cost){
    G[u].emplace_back(v,cap,cost,G[v].size());
    G[v].emplace_back(u,0,-cost,G[u].size()-1);
  }

  void dijkstra(Int s){
    struct P{
      TC first;
      Int second;
      P(TC first,Int second):first(first),second(second){}
      bool operator<(const P&a) const{return first>a.first;}
    };
    priority_queue<P> que;
    fill(dist.begin(),dist.end(),INF);

    dist[s]=0;
    que.emplace(dist[s],s);
    while(!que.empty()){
      P p=que.top();que.pop();
      Int v=p.second;
      if(dist[v]<p.first) continue;
      for(Int i=0;i<(Int)G[v].size();i++){
        edge &e=G[v][i];
        if(e.cap==0) continue;
        if(dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
          dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
          prevv[e.to]=v;
          preve[e.to]=i;
          que.emplace(dist[e.to],e.to);
        }
      }
    }
  }

  TC flow(Int s,Int t,TF f,Int &ok){
    TC res=0;
    fill(h.begin(),h.end(),0);
    while(f>0){
      dijkstra(s);
      if(dist[t]==INF) return ok=0;

      for(Int v=0;v<(Int)h.size();v++) h[v]+=dist[v];

      TF d=f;
      for(Int v=t;v!=s;v=prevv[v])
        d=min(d,G[prevv[v]][preve[v]].cap);

      f-=d;
      res+=d*h[t];
      for(Int v=t;v!=s;v=prevv[v]){
        edge &e=G[prevv[v]][preve[v]];
        e.cap-=d;
        G[v][e.rev].cap+=d;
      }
    }
    ok=1;
    return res;
  }
};
template<typename TF, typename TC> constexpr TC PrimalDual<TF, TC>::INF;

//INSERT ABOVE HERE
signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  Int n;
  cin>>n;
  const Int INF = 1e9;

  Int S=n+1,T=n+2;
  PrimalDual<Int, Int> G(n+3);
  Int num=0,ans=0;

  vector<Int> ds(n+1,0);
  ds[0]=INF;
  ds[n]=-INF;

  for(Int i=0;i<n;i++){
    Int k;
    cin>>k;
    num+=k;
    map<Int, Int> dst;
    for(Int j=0;j<k;j++){
      Int t,c;
      cin>>t>>c;
      t--;
      ds[i]--;
      ds[t]++;
      ans+=c;
      if(!dst.count(t)) dst[t]=c;
      chmin(dst[t],c);
    }

    for(auto p:dst)
      G.add_edge(i,p.first,INF,p.second);

    G.add_edge(i,n,INF,0);
  }

  Int sum=0;
  for(Int i=0;i<=n;i++){
    if(ds[i]>0){
      sum+=ds[i];
      G.add_edge(S,i,+ds[i],0);
    }
    if(ds[i]<0){
      G.add_edge(i,T,-ds[i],0);
    }
  }

  Int ok=1;
  ans+=G.flow(S,T,sum,ok);
  cout<<ans<<endl;
  assert(ok);
  return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 5444
final_rank: 3

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

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b)a=b;};


template<typename T>
struct PrimalDual{
  struct edge{
    Int to;
    T cap,cost;
    Int rev;
    edge(){}
    edge(Int to,T cap,T cost,Int rev):to(to),cap(cap),cost(cost),rev(rev){}
  };
  
  T INF;
  vector<vector<edge> > G;
  vector<T> h,dist;
  vector<Int> prevv,preve;

  PrimalDual(){}
  PrimalDual(Int n,T INF):INF(INF),G(n),h(n),dist(n),prevv(n),preve(n){}
  
  void add_edge(Int from,Int to,T cap,T cost){
    G[from].emplace_back(to,cap,cost,G[to].size());
    G[to].emplace_back(from,0,-cost,G[from].size()-1);
  }

  T flow(Int s,Int t,T f,Int &ok){    
    T res=0;
    fill(h.begin(),h.end(),0);
    while(f>0){    
      struct P{
        T first;
        Int second;
        P(T first,Int second):first(first),second(second){}
        bool operator<(const P&a) const{return first>a.first;}
      };      
      priority_queue<P> que;
      
      fill(dist.begin(),dist.end(),INF);
      
      dist[s]=0;
      que.emplace(dist[s],s);
      while(!que.empty()){
        P p=que.top();que.pop();
        Int v=p.second;
        if(dist[v]<p.first) continue;
        for(Int i=0;i<(Int)G[v].size();i++){
          edge &e=G[v][i];
          if(e.cap==0) continue;
          if(dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
            dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
            prevv[e.to]=v;
            preve[e.to]=i;
            que.emplace(dist[e.to],e.to);
          }
        }
      }
      if(dist[t]==INF) return ok=0;
      
      for(Int v=0;v<(Int)h.size();v++) h[v]+=dist[v];

      T d=f;
      for(Int v=t;v!=s;v=prevv[v])
        d=min(d,G[prevv[v]][preve[v]].cap);
      
      f-=d;
      res+=d*h[t];
      for(Int v=t;v!=s;v=prevv[v]){
        edge &e=G[prevv[v]][preve[v]];
        e.cap-=d;
        G[v][e.rev].cap+=d;
      }
    }
    ok=1;
    return res;
  }
};

//INSERT ABOVE HERE
signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);
  
  Int n;
  cin>>n;
  const Int INF2 = 1e9;
  const Int INF3 = 1e15;
  PrimalDual<Int> G(n+1,INF3);
  Int num=0,ans=0;
  for(Int i=0;i<n;i++){   
    Int k;
    cin>>k;
    num+=k;
    map<Int, Int> cnt,dst;
    for(Int j=0;j<k;j++){
      Int t,c;
      cin>>t>>c;
      t--;
      cnt[t]++;
      ans+=c+INF2;
      if(!dst.count(t)) dst[t]=c;
      chmin(dst[t],c);
    }
    
    for(auto p:cnt){
      G.add_edge(i,p.first,cnt[p.first],-INF2);
      G.add_edge(i,p.first,INF2,dst[p.first]);      
    }
      
    G.add_edge(i,n,INF2,0);
  }
  
  Int ok=1;
  ans+=G.flow(0,n,INF2,ok);  
  cout<<ans<<endl; 
  assert(ok);
  return 0;
}
accuracy: 1
time_ms: 4410
memory_kb: 7640
final_rank: 9

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

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b)a=b;};
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b)a=b;};


template<typename T>
struct PrimalDual{
  struct edge{
    Int to;
    T cap,cost;
    Int rev;
    edge(){}
    edge(Int to,T cap,T cost,Int rev):to(to),cap(cap),cost(cost),rev(rev){}
  };
  
  T INF;
  vector<vector<edge> > G;
  vector<T> h,dist;
  vector<Int> prevv,preve;

  PrimalDual(){}
  PrimalDual(Int n,T INF):INF(INF),G(n),h(n),dist(n),prevv(n),preve(n){}
  
  void add_edge(Int from,Int to,T cap,T cost){
    G[from].emplace_back(to,cap,cost,G[to].size());
    G[to].emplace_back(from,0,-cost,G[from].size()-1);
  }

  T flow(Int s,Int t,T f,Int &ok){    
    T res=0;
    fill(h.begin(),h.end(),0);
    while(f>0){    
      struct P{
        T first;
        Int second;
        P(T first,Int second):first(first),second(second){}
        bool operator<(const P&a) const{return first>a.first;}
      };
      
      priority_queue<P> que;
      
      fill(dist.begin(),dist.end(),INF);
      
      dist[s]=0;
      que.emplace(dist[s],s);
      while(!que.empty()){
        P p=que.top();que.pop();
        Int v=p.second;
        if(dist[v]<p.first) continue;
        for(Int i=0;i<(Int)G[v].size();i++){
          edge &e=G[v][i];
          if(e.cap==0) continue;
          if(dist[e.to]>dist[v]+e.cost+h[v]-h[e.to]){
            dist[e.to]=dist[v]+e.cost+h[v]-h[e.to];
            prevv[e.to]=v;
            preve[e.to]=i;
            que.emplace(dist[e.to],e.to);
          }
        }
      }
      if(dist[t]==INF) return ok=0;
      
      for(Int v=0;v<(Int)h.size();v++) h[v]+=dist[v];

      T d=f;
      for(Int v=t;v!=s;v=prevv[v])
        d=min(d,G[prevv[v]][preve[v]].cap);
      
      f-=d;
      res+=d*h[t];
      for(Int v=t;v!=s;v=prevv[v]){
        edge &e=G[prevv[v]][preve[v]];
        e.cap-=d;
        G[v][e.rev].cap+=d;
      }
    }
    ok=1;
    return res;
  }
};

//INSERT ABOVE HERE
signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);
  
  Int n;
  cin>>n;
  const Int INF2 = 1e9;
  const Int INF3 = 1e15;
  PrimalDual<Int> G(n+1,INF3);
  Int num=0,ans=0;
  for(Int i=0;i<n;i++){   
    Int k;
    cin>>k;
    num+=k;
    map<Int, Int> cnt,dst;
    for(Int j=0;j<k;j++){
      Int t,c;
      cin>>t>>c;
      t--;
      cnt[t]++;
      ans+=c+INF2;
      if(!dst.count(t)) dst[t]=c;
      chmin(dst[t],c);
    }
    
    for(auto p:cnt){
      G.add_edge(i,p.first,cnt[p.first],-INF2);
      G.add_edge(i,p.first,INF2,dst[p.first]);      
    }
      
    G.add_edge(i,n,INF2,0);
  }
  
  Int ok=1;
  ans+=G.flow(0,n,INF2,ok);  
  cout<<ans<<endl; 
  assert(ok);
  return 0;
}
accuracy: 1
time_ms: 4430
memory_kb: 7644
final_rank: 10