#include <bits/stdc++.h>
using namespace std;
int INF = 1e9;
struct UnionFind {
  vector<int> par, rank;
  void init(int n) {
    par.clear();
    rank.clear();
    par.resize(n);
    rank.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 1;
    }
  }
  int find(int x) {
    if (x == par[x]) return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return (find(x) == find(y)); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y]) swap(x, y);
    par[y] = x;
    rank[x] += rank[y];
  }
};
struct edge {
  int from, to, cost, id;
  bool operator<(const edge e) const { return cost > e.cost; }
};
typedef priority_queue<edge> *Prque;
Prque Merge(Prque a, Prque b, int da, int db) {
  if (a->size() < b->size()) {
    swap(a, b);
    swap(da, db);
  }
  while (!b->empty()) {
    edge e = b->top();
    e.cost -= db;
    e.cost += da;
    a->push(e);
    b->pop();
  }
  return a;
}
int solve(vector<vector<edge> > &G, vector<edge> &edges, int root) {
  int n = G.size(), res = 0;
  vector<int> used(n, 0);
  vector<edge> ev(n, (edge){0, 0, 0, -1});
  vector<priority_queue<edge> > pool(n);
  vector<Prque> Q(n);
  for (int i = 0; i < n; i++) Q[i] = &pool[i];
  UnionFind uf;
  uf.init(n);
  for (int i = 0; i < (int)edges.size(); i++) {
    edge e = edges[i];
    Q[e.to]->push(e);
  }
  used[root] = 2;
  for (int Pos = 0; Pos < n; Pos++) {
    if (used[Pos] == 2) continue;
    int pos = Pos;
    vector<int> path;
    while (used[pos] != 2) {
      pos = uf.find(pos);
      used[pos] = 1;
      path.push_back(pos);
      if (Q[pos]->empty()) {
        return INF;
      }
      edge e = Q[pos]->top();
      Q[pos]->pop();
      e.cost -= ev[pos].cost;
      if (uf.same(e.from, pos)) continue;
      int tmpcost = ev[pos].cost;
      res += e.cost;
      e.cost += tmpcost;
      ev[pos] = e;
      if (used[uf.find(e.from)] == 2) break;
      if (used[uf.find(e.from)] == 0) {
        pos = e.from;
        continue;
      }
      int pre = uf.find(e.from);
      for (int i = 0; i < 100; i++) {
        if (!uf.same(pre, pos)) {
          int A = uf.find(pre), B = uf.find(pos);
          uf.unite(A, B);
          int C = uf.find(A);
          Prque tmp = Merge(Q[A], Q[B], ev[A].cost, ev[B].cost);
          Q[C] = tmp;
        }
        pre = uf.find(ev[pre].from);
      }
    }
    for (int i = 0; i < (int)path.size(); i++) used[path[i]] = 2;
  }
  return res;
}
int main() {
  int V, E, r;
  vector<edge> edges;
  vector<vector<edge> > G;
  cin >> V >> E >> r;
  G.resize(V);
  for (int i = 0; i < E; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    G[a].push_back((edge){a, b, c, i});
    edges.push_back((edge){a, b, c, i});
  }
  cout << solve(G, edges, r) << endl;
  return 0;
}
