#include <bits/stdc++.h>
using namespace std;
struct Edge {
  long long from, to, cost;
  Edge *prevEdge;
  Edge(long long from, long long to, long long cost, Edge *prevEdge = NULL)
      : from(from), to(to), cost(cost), prevEdge(prevEdge) {}
};
struct UnionFindTree {
  vector<long long> par, sz;
  UnionFindTree(long long n) {
    par.resize(n);
    sz.resize(n);
    for (long long i = 0; i < n; i++) {
      par[i] = i;
      sz[i] = 1;
    }
  }
  long long find(long long x) {
    return x == par[x] ? x : par[x] = find(par[x]);
  }
  void unite(long long x, long long y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (sz[x] < sz[y]) swap(x, y);
    sz[x] += sz[y];
    par[y] = x;
  }
  bool areSame(long long x, long long y) { return find(x) == find(y); }
  long long size(long long x) { return sz[find(x)]; }
};
vector<vector<Edge>> maximumWeightBranching(vector<vector<Edge>> G) {
  const long long INF = 1001001001;
  long long N = G.size();
  vector<Edge> maxEdge(N, Edge(-1, -1, 0));
  for (long long v = 0; v < N; v++)
    for (auto &e : G[v])
      if (maxEdge[e.to].cost < e.cost) maxEdge[e.to] = e;
  UnionFindTree uf(N);
  vector<long long> isInC(N);
  for (long long i = 0; i < N; i++) {
    if (maxEdge[i].from == -1) continue;
    if (uf.areSame(maxEdge[i].from, i)) {
      for (long long j = 0; j < N; j++)
        if (uf.areSame(j, i)) isInC[j] = 1;
      break;
    } else {
      uf.unite(maxEdge[i].from, i);
    }
  }
  if (find(isInC.begin(), isInC.end(), 1) == isInC.end()) {
    vector<vector<Edge>> ret(N);
    for (long long i = 0; i < N; i++)
      if (maxEdge[i].from != -1) ret[maxEdge[i].from].push_back(maxEdge[i]);
    return ret;
  }
  vector<long long> newIndex(N);
  for (long long i = 0; i < N; i++)
    newIndex[i] = (i ? newIndex[i - 1] : -1) + (isInC[i] == 0);
  long long n = newIndex[N - 1] + 2;
  vector<vector<Edge>> g(n);
  Edge minC(-1, -1, INF);
  for (long long i = 0; i < N; i++) {
    if (isInC[i]) {
      if (minC.cost > maxEdge[i].cost) minC = maxEdge[i];
      newIndex[i] = n - 1;
    }
  }
  for (long long v = 0; v < N; v++)
    for (auto &e : G[v]) {
      long long u = e.to;
      if (isInC[v] && isInC[u]) continue;
      if (!isInC[v] && isInC[u]) {
        g[newIndex[v]].push_back(Edge(newIndex[v], newIndex[u],
                                      e.cost + minC.cost - maxEdge[u].cost,
                                      &e));
      } else {
        g[newIndex[v]].push_back(Edge(newIndex[v], newIndex[u], e.cost, &e));
      }
    }
  g = maximumWeightBranching(g);
  if (g.size() == 0) return vector<vector<Edge>>();
  vector<vector<Edge>> ret(N);
  for (long long v = 0; v < n; v++) {
    for (auto &e : g[v]) {
      if (v != n - 1 && e.to == n - 1) minC = maxEdge[e.prevEdge->to];
      ret[e.prevEdge->from].push_back(*e.prevEdge);
    }
  }
  for (long long i = 0; i < N; i++)
    if (isInC[i] && maxEdge[i].to != minC.to)
      ret[maxEdge[i].from].push_back(maxEdge[i]);
  return ret;
}
long long maximumWeightBranching(vector<long long> A, vector<long long> B,
                                 vector<long long> C) {
  long long N =
      max(*max_element(A.begin(), A.end()), *max_element(B.begin(), B.end())) +
      1;
  vector<vector<Edge>> G(N);
  for (long long i = 0; i < A.size(); i++)
    G[A[i]].push_back(Edge(A[i], B[i], C[i]));
  G = maximumWeightBranching(G);
  if (G.size() == 0) return -1;
  long long ret = 0;
  for (long long i = 0; i < N; i++)
    for (auto &e : G[i]) ret += e.cost;
  return ret;
}
long long minimumWeightArborescence(vector<long long> A, vector<long long> B,
                                    vector<long long> C) {
  long long N =
      max(*max_element(A.begin(), A.end()), *max_element(B.begin(), B.end())) +
      1;
  long long K = 0;
  for (long long i = 0; i < C.size(); i++) K += abs(C[i]);
  K = 2 * K + 1;
  for (long long i = 0; i < C.size(); i++) C[i] = K - C[i];
  long long ret = maximumWeightBranching(A, B, C);
  if (ret == -1) return -1;
  return K * (N - 1) - ret;
}
long long minimumWeightRootedArborescence(vector<long long> A,
                                          vector<long long> B,
                                          vector<long long> C, long long r) {
  long long s =
      max(*max_element(A.begin(), A.end()), *max_element(B.begin(), B.end())) +
      1;
  A.push_back(s);
  B.push_back(r);
  C.push_back(0);
  return minimumWeightArborescence(A, B, C);
}
signed main() {
  long long N, M, r;
  cin >> N >> M >> r;
  vector<long long> A(M), B(M), C(M);
  for (long long i = 0; i < M; i++) cin >> A[i] >> B[i] >> C[i];
  cout << minimumWeightRootedArborescence(A, B, C, r) << endl;
}
