#include <bits/stdc++.h>
using namespace std;
const int MAX_V = 105;
const int INF = 1e9;
struct edge {
  int from, to, cost;
};
void visit(vector<vector<edge> > &h, int v, int s, int r, vector<int> &no,
           vector<vector<int> > &comp, vector<int> &prev,
           vector<vector<int> > &next, vector<int> &mcost, vector<int> &mark,
           int &cost, bool &found) {
  const int n = h.size();
  if (mark[v]) {
    vector<int> temp = no;
    found = true;
    do {
      cost += mcost[v];
      v = prev[v];
      if (v != s) {
        while (comp[v].size() > 0) {
          no[comp[v].back()] = s;
          comp[s].push_back(comp[v].back());
          comp[v].pop_back();
        }
      }
    } while (v != s);
    for (int i = 0; i < (int)(comp[s].size()); ++i)
      if (comp[s][i] != r)
        for (int j = 0; j < (int)(h[comp[s][i]].size()); ++j) {
          edge e = h[comp[s][i]][j];
          if (no[e.from] != s) e.cost -= mcost[temp[comp[s][i]]];
        }
  }
  mark[v] = true;
  for (int i = 0; i < (int)(next[v].size()); ++i)
    if (no[next[v][i]] != no[v] && prev[no[next[v][i]]] == v)
      if (!mark[no[next[v][i]]] || next[v][i] == s)
        visit(h, next[v][i], s, r, no, comp, prev, next, mcost, mark, cost,
              found);
}
int minimumSpanningArborescence(int V, int E, vector<vector<edge> > &G, int r) {
  vector<vector<edge> > h(V);
  for (int i = 0; i < (int)(V); ++i)
    for (int j = 0; j < (int)(G[i].size()); ++j)
      h[G[i][j].to].push_back(G[i][j]);
  vector<int> no(V);
  vector<vector<int> > comp(V);
  for (int i = 0; i < (int)(V); ++i) comp[i].push_back(no[i] = i);
  for (int cost = 0;;) {
    vector<int> prev(V, -1);
    vector<int> mcost(V, INF);
    for (int i = 0; i < (int)(V); ++i) {
      for (int j = 0; j < (int)(G[i].size()); ++j) {
        edge e = G[i][j];
        if (e.to == r) continue;
        if (e.cost < mcost[no[e.to]]) {
          mcost[no[e.to]] = e.cost;
          prev[no[e.to]] = no[i];
        }
      }
    }
    vector<vector<int> > next(V);
    for (int i = 0; i < (int)(V); ++i)
      if (prev[i] >= 0) next[prev[i]].push_back(i);
    bool stop = true;
    vector<int> mark(V);
    for (int i = 0; i < (int)(V); ++i)
      if (i != r && !mark[i] && !comp[i].empty()) {
        bool found = false;
        visit(h, i, i, r, no, comp, prev, next, mcost, mark, cost, found);
        if (found) stop = false;
      }
    if (stop) {
      for (int i = 0; i < (int)(V); ++i)
        if (prev[i] >= 0) cost += mcost[i];
      return cost;
    }
  }
}
int main() {
  int V, E, r;
  cin >> V >> E >> r;
  vector<vector<edge> > G(V);
  for (int i = 0; i < (int)(E); ++i) {
    edge e;
    cin >> e.from >> e.to >> e.cost;
    G[e.from].push_back(e);
  }
  cout << minimumSpanningArborescence(V, E, G, r) << endl;
  return 0;
}
