#include <bits/stdc++.h>
using namespace std;
struct graph_t {
  int n;
  int m;
  vector<pair<int, int> > edges;
  vector<long long int> cost;
  vector<long long int> cap;
};
class Chuliu_Edmonds {
 private:
  struct fromedge {
    int eid;
    int id;
    long long int cost;
    stack<int> included_stk;
    bool operator<(const fromedge &another) const {
      return !(cost != another.cost ? cost < another.cost : id < another.id);
    }
  };
  struct node {
    int overnode;
    bool done;
    bool fin;
    priority_queue<fromedge> from_edges;
    fromedge from;
  };
  vector<node> nodes;
  int n, root;
  int topnode(int a) {
    while (nodes[a].overnode != -1) a = nodes[a].overnode;
    return a;
  }
  void contract(int s) {
    int a = s;
    priority_queue<fromedge> new_from_edges;
    do {
      a = topnode(a);
      priority_queue<fromedge> from_ebuf = nodes[a].from_edges;
      while (from_ebuf.size()) {
        fromedge from_e = from_ebuf.top();
        from_ebuf.pop();
        if (nodes[from_e.id].done && !nodes[from_e.id].fin) continue;
        from_e.cost -= nodes[a].from.cost;
        from_e.included_stk.push(a);
        new_from_edges.push(from_e);
      }
      nodes[a].overnode = nodes.size();
      a = nodes[a].from.id;
    } while (a != s);
    nodes.push_back({-1, false, false, new_from_edges, {}});
  }
  void unfold(stack<int> *stk) {
    while (stk->size()) {
      int a = stk->top();
      stk->pop();
      if (a >= n) {
        int b = nodes[a].from.included_stk.top();
        long long int d = nodes[b].from.cost;
        nodes[b].from = nodes[a].from;
        nodes[b].from.cost += d;
        nodes[b].from.included_stk.pop();
      } else {
        nodes[a].fin = true;
      }
    }
  }

 public:
  Chuliu_Edmonds(graph_t G, int start) {
    n = G.n;
    nodes.resize(n);
    for (int i = 0; i < (int)n; i++) nodes[i] = {-1, false, false, {}, {}};
    for (int i = 0; i < (int)G.edges.size(); i++) {
      nodes[G.edges[i].second].from_edges.push(
          {i, G.edges[i].first, G.cost[i], {}});
    }
    root = start;
    nodes[root].fin = nodes[root].done = true;
    for (int i = 0; i < (int)n; i++) {
      if (!nodes[i].fin) {
        int a = i;
        stack<int> stk;
        nodes[a].done = true;
        stk.push(a);
        while (1) {
          nodes[a].from = nodes[a].from_edges.top();
          int b = nodes[a].from.id;
          if (nodes[b].fin) {
            unfold(&stk);
            break;
          } else if (nodes[b].done) {
            contract(b);
            stk.push(nodes.size() - 1);
            a = nodes.size() - 1;
          } else {
            nodes[b].done = true;
            stk.push(b);
            a = b;
          }
        }
      }
    }
  }
  vector<pair<int, int> > get_tree_idpair() {
    vector<pair<int, int> > ret;
    for (int i = 0; i < (int)n; i++) {
      if (i != root) ret.push_back({nodes[i].from.id, i});
    }
    return ret;
  }
  vector<int> get_tree_eid() {
    vector<int> ret;
    for (int i = 0; i < (int)n; i++) {
      if (i != root) ret.push_back(nodes[i].from.eid);
    }
    return ret;
  }
  long long int get_weight() {
    long long int ret = 0;
    for (int i = 0; i < (int)n; i++) {
      if (i != root) ret += nodes[i].from.cost;
    }
    return ret;
  }
};
int main() {
  graph_t G;
  cin >> G.n >> G.m;
  int r;
  cin >> r;
  for (int i = 0; i < (int)G.m; i++) {
    int s, t, c;
    cin >> s >> t >> c;
    G.edges.push_back({s, t});
    G.cost.push_back(c);
  }
  Chuliu_Edmonds mca(G, r);
  cout << mca.get_weight() << endl;
}
