#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

// SCC Strongly Connected Component 強連結成分分解
struct SCC {
	typedef vector<vector<int>> graph;

	int V;
	int cV;
	graph G;
	graph cG;
	vector<int> cmp;
	vector<int> vs;
	vector<bool> used;

	SCC(int V_):V(V_), G(V_), cmp(V_), used(V_) {}
	SCC(const graph &G_):V(G_.size()), G(G_), cmp(V), used(V) {}

	void add_edge(int from, int to) {
		G[from].emplace_back(to);
	}

	void dfs(int v) {
		used[v] = true;
		for(const auto &to : G[v]) {
			if(!used[to]) dfs(to);
		}
		vs.emplace_back(v);
	}

	void rdfs(int v, int k, graph &rG) {
		used[v] = true;
		cmp[v] = k;
		for(const auto &to : rG[v]) {
			if(!used[to]) rdfs(to, k, rG);
		}
	}

	int scc() {
		vs.clear();
		fill(used.begin(), used.end(), false);

		for(int v = 0; v < V; ++v) {
			if(!used[v]) dfs(v);
		}

		graph rG(V);
		for(int v = 0; v < V; ++v) {
			for(const auto &to : G[v]) {
				rG[to].emplace_back(v);
			}
		}

		fill(used.begin(), used.end(), false);
		int k = 0;
		for(int i = static_cast<int>(vs.size()) - 1; i >= 0; --i) {
			if(!used[vs[i]]) rdfs(vs[i], k++, rG);
		}
		return k;
	}

	void construct() {
		cV = scc();
		cG.clear();
		cG.resize(cV);

		for(int v = 0; v < V; ++v) {
			for(const auto &to : G[v]) {
				if(cmp[v] != cmp[to]) cG[cmp[v]].emplace_back(cmp[to]);
			}
		}

		for(auto &es : cG) {
			sort(es.begin(), es.end());
			es.erase(unique(es.begin(), es.end()), es.end());
		}
	}
};

typedef int weight;
constexpr weight INF = (1 << 28);

struct edge {
	int to;
	weight cost;
	edge(int to_, weight cost_):to(to_), cost(cost_){}
};

typedef vector<vector<edge>> weighted_graph;

weight minimum_spanning_arborescence(int r, const weighted_graph &G, weight sum = 0) {
	const int n = G.size();

	vector<int> rev(n, -1);
	vector<weight> minimum_weight(n, INF);
	for(int v = 0; v < n; ++v) {
		for(const auto &e : G[v]) {
			if(minimum_weight[e.to] > e.cost) {
				minimum_weight[e.to] = e.cost;
				rev[e.to] = v;
			}
		}
	}

	SCC scc(n);
	for(int v = 0; v < n; ++v) {
		if(v == r) continue;
		if(rev[v] == -1) return INF;
		scc.add_edge(rev[v], v);
		sum += minimum_weight[v];
	}

	const int num = scc.scc();
	if(num == n) return sum;

	weighted_graph next_G(num);
	for(int v = 0; v < n; ++v) {
		const int from = scc.cmp[v];
		for(const auto &e : G[v]) {
			const int to = scc.cmp[e.to];
			if(from == to) continue;

			const int cost = e.cost - minimum_weight[e.to];
			next_G[from].emplace_back(to, cost);
		}
	}

	return minimum_spanning_arborescence(scc.cmp[r], next_G, sum);
}

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

	int n, m, r;
	cin >> n >> m >> r;

	weighted_graph G(n);
	for(int i = 0; i < m; ++i) {
		int from, to, cost;
		cin >> from >> to >> cost;
		G[from].emplace_back(to, cost);
	}

	cout << minimum_spanning_arborescence(r, G) << endl;

	return EXIT_SUCCESS;
}