#include <bits/stdc++.h>
using namespace std;
vector<bool> used;
struct Edge {
  int to, cost;
  Edge(int to, int cost) : to(to), cost(cost) {}
  bool operator<(const Edge& o) const { return cost < o.cost; }
};
void dfs1(vector<vector<Edge>>& H, int v, stack<int>& st) {
  used[v] = true;
  for (Edge& e : H[v]) {
    if (!used[e.to]) dfs1(H, e.to, st);
  }
  st.push(v);
}
void dfs2(vector<Edge>& rH, int v, int timer, vector<int>& comp) {
  used[v] = true;
  comp[v] = timer;
  if (rH[v].to != (1 << 30)) {
    if (!used[rH[v].to]) {
      dfs2(rH, rH[v].to, timer, comp);
    }
  }
}
int scc(vector<vector<Edge>>& H, vector<Edge>& rH, int r, int n,
        vector<int>& comp) {
  stack<int> st;
  dfs1(H, r, st);
  fill(used.begin(), used.end(), false);
  int timer = 0;
  while (!st.empty()) {
    int v = st.top();
    st.pop();
    if (!used[v]) {
      dfs2(rH, v, timer, comp);
      timer++;
    }
  }
  return timer;
}
int Minimum_Cost_Arborescence(vector<vector<Edge>>& G, int r) {
  int n = G.size();
  int ret = 0;
  used.assign(n, false);
  vector<vector<Edge>> H(n);
  vector<Edge> rH(n, Edge((1 << 30), (1 << 30)));
  for (int s = 0; s < n; s++) {
    for (int i = 0; i < G[s].size(); i++) {
      Edge& e = G[s][i];
      if (e.to == r) continue;
      if (e < rH[e.to]) {
        if (rH[e.to].to == (1 << 30)) {
          ret += e.cost;
        } else {
          ret -= rH[e.to].cost - e.cost;
        }
        rH[e.to] = Edge(s, e.cost);
        continue;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    int to = rH[i].to;
    if (to != (1 << 30)) {
      H[to].emplace_back(i, rH[i].cost);
    }
  }
  vector<int> comp(n);
  int c = scc(H, rH, r, n, comp);
  if (c == n) return ret;
  vector<int> num_comp(c, 0);
  for (int i = 0; i < n; i++) {
    num_comp[comp[i]]++;
  }
  vector<vector<Edge>> next_G(c);
  for (int v = 0; v < n; v++) {
    for (Edge& e : H[v]) {
      int next_from = comp[v], next_to = comp[e.to];
      if (next_from == next_to) continue;
      if (num_comp[next_to] == 1) {
        next_G[next_from].emplace_back(Edge(next_to, e.cost));
      } else {
        next_G[next_from].emplace_back(Edge(next_to, e.cost - rH[e.to].cost));
      }
    }
  }
  return Minimum_Cost_Arborescence(next_G, comp[r]);
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int V, E, r;
  cin >> V >> E >> r;
  vector<vector<Edge>> G(V);
  for (int i = 0; i < E; i++) {
    int s, t, w;
    cin >> s >> t >> w;
    G[s].emplace_back(Edge(t, w));
  }
  cout << Minimum_Cost_Arborescence(G, r) << endl;
}
