#include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using ll = long long;
using P = pair<int, int>;

#define INF 1001001001

struct Edge {
  int from;
  int to;
  int cost;
  Edge(int from, int to, int cost) : from(from), to(to), cost(cost) {}
};

using Graph = vector< vector<Edge> >;

int dfs(Graph G, int r) {
  int n = G.size();
  vector<int> minEdge(n,-1);
  vector<int> minCost(n,INF);

  // T*構成
  for (auto es : G) {
    for (auto e : es) {
      if (e.to == r) continue;
      if (e.cost < minCost[e.to]) {
        minEdge[e.to] = e.from;
        minCost[e.to] = e.cost;
      }
    }
  }

  // 閉路検出
  int v = -1;
  rep(i,n) {
    if (minEdge[i]==-1) continue;
    vector<bool> isVisited(n);
    int now = i;
    while (now != r && !isVisited[now]) {
      isVisited[now] = true;
      now = minEdge[now];
    }
    if (now != r) {
      v = now;
      break;
    }
  }

  // 閉路なしの場合
  if (v == -1) {
    int ans = 0;
    rep(i,n) {
      if (minEdge[i]==-1) continue;
      ans += minCost[i];
    }
    return ans;
  }

  // 閉路ありの場合
  int ans = 0;
  int now = v;
  vector<bool> onCycle(n);
  while (!onCycle[now]) {
    onCycle[now] = true;
    ans += minCost[now];
    now = minEdge[now];
  }

  // グラフを縮約
  Graph newG(n);
  rep(i,n) {
    for (auto e : G[i]) {
      int s = e.from;
      int t = e.to;
      int c = e.cost;
      if (t == r) continue;
      if (onCycle[s] && onCycle[t]) continue;
      if (onCycle[t]) {
        c -= minCost[t];
        t = v;
      }
      if (onCycle[s]) s = v;
      newG[i].emplace_back(s,t,c);
    }
  }
  ans += dfs(newG,r);

  return ans;
}

int main() {
  int v, e, r;
  cin >> v >> e >> r;
  vector< vector<Edge> > G(v);
  rep(i,e) {
    int s, t, w;
    cin >> s >> t >> w;
    G[t].emplace_back(s,t,w);
  }

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

  return 0;
}
