#include <bits/stdc++.h>
using namespace std;
template <class T>
struct PairingNode {
  typedef struct PairingNode<T>* pnode;
  T val;
  pnode child, left, right;
};
template <class T>
PairingNode<T>* _pairingnewnode(T val) {
  typedef struct PairingNode<T>* pnode;
  pnode _new = new PairingNode<T>();
  _new->val = val;
  return _new;
}
template <class T>
struct pairing {
  typedef struct PairingNode<T>* pnode;
  pnode root = 0;
  int sz = 0;
  int size() { return sz; }
  bool empty() { return !sz; }
  T top() { return root->val; }
  void swap(pnode& a, pnode& b) {
    pnode c = a;
    a = b;
    b = c;
  }
  pnode merge(pnode a, pnode b) {
    if (!b) return a;
    if (!a) return b;
    if (b->val < a->val) swap(a, b);
    b->right = a->child;
    if (b->right) b->right->left = b;
    a->child = b;
    b->left = a;
    return a;
  }
  void merge(pairing* a) {
    sz += a->sz;
    root = merge(root, a->root);
  }
  void push(pnode _new) {
    sz++;
    if (sz == 1) {
      root = _new;
      return;
    }
    if (_new->val < root->val) {
      _new->child = root;
      root->left = _new;
      root = _new;
    } else {
      _new->right = root->child;
      if (_new->right) _new->right->left = _new;
      root->child = _new;
      _new->left = root;
    }
  }
  pnode push(T val) {
    pnode _new = _pairingnewnode<T>(val);
    push(_new);
    return _new;
  }
  pnode recursivemerge(pnode a) {
    if (!a) return a;
    pnode b = a->right;
    if (!b) return a;
    pnode c = b->right;
    return merge(merge(a, b), recursivemerge(c));
  }
  void pop() {
    sz--;
    root = recursivemerge(root->child);
    if (root) root->right = nullptr;
  }
  void decreasekey(pnode a, T val) {
    a->val = val;
    if (a == root) return;
    if (a->left->child == a) {
      a->left->child = a->right;
      if (a->right) a->right->left = a->left;
      a->left = a->right = nullptr;
      root = merge(root, a);
    } else {
      a->left->right = a->right;
      if (a->right) a->right->left = a->left;
      a->left = a->right = nullptr;
      root = merge(root, a);
    }
  }
};
struct UF {
  int rep[2 * 100010], val[2 * 100010], valatroot[2 * 100010];
  void init() {
    for (int i = 0; i < 2 * 100010; i++) rep[i] = i, val[i] = valatroot[i] = 0;
  }
  int findrep(int a) {
    if (rep[a] == a) return a;
    int b = rep[a];
    rep[a] = findrep(b);
    val[a] += valatroot[a] + val[b];
    valatroot[a] = 0;
    return rep[a] = rep[b];
  }
  bool connected(int a, int b) { return findrep(a) == findrep(b); }
  void merge(int a, int b) { rep[findrep(a)] = findrep(b); }
  void addval(int a, int val) { valatroot[findrep(a)] += val; }
  int findval(int a) {
    int b = findrep(a);
    return val[a] + valatroot[b];
  }
};
UF scc, wcc;
struct Edge {
  int u, v, weight;
  Edge(int U, int V, int WEIGHT) { u = U, v = V, weight = WEIGHT; }
  Edge() {}
  int val() const { return weight - scc.findval(v); }
  bool operator<(const Edge e) const { return val() < e.val(); }
};
pairing<Edge>* incoming[2 * 100010];
Edge par[2 * 100010];
int minimalbranching(int n, int root, vector<pair<int, int> >* adj) {
  scc.init(), wcc.init();
  int ans = 0, upto = 100010;
  for (int i = 0; i < 2 * 100010; i++) incoming[i] = new pairing<Edge>();
  for (int i = 0; i < n; i++) {
    for (auto b : adj[i]) {
      incoming[b.first]->push(Edge(i, b.first, b.second));
    }
  }
  queue<int> q;
  for (int i = 0; i < n; i++)
    if (i != root) q.push(i);
  while (q.size()) {
    int a = q.front();
    q.pop();
    if (scc.findrep(a) != a) continue;
    while (1) {
      if (incoming[a]->empty()) return -1;
      if (scc.connected(incoming[a]->top().u, a))
        incoming[a]->pop();
      else
        break;
    }
    par[a] = incoming[a]->top();
    ans += par[a].val();
    incoming[a]->pop();
    if (!wcc.connected(par[a].u, par[a].v)) {
      wcc.merge(par[a].u, par[a].v);
    } else {
      Edge mx = par[a];
      int b = scc.findrep(par[a].u);
      while (b != a) {
        mx = max(mx, par[b]);
        b = scc.findrep(par[b].u);
      }
      ans -= mx.val();
      int s = upto++;
      b = scc.findrep(par[a].u);
      while (b != s) {
        scc.addval(b, par[b].val() - mx.val());
        incoming[s]->merge(incoming[b]);
        scc.merge(b, s);
        b = scc.findrep(par[b].u);
      }
      q.push(s);
    }
  }
  return ans;
}
vector<pair<int, int> > adj[100010];
int main() {
  int n, m, r;
  scanf("%d%d%d", &n, &m, &r);
  for (int i = 0; i < m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    adj[a].emplace_back(b, c);
  }
  int ans = minimalbranching(n, r, adj);
  printf("%d\n", ans);
}
