#include <bits/stdc++.h>
using namespace std;
class Prim {
 private:
  struct Order {
    bool operator()(pair<long, long> const& a,
                    pair<long, long> const& b) const {
      return a.first > b.first ||
             ((a.first == b.first) && (a.second > b.second));
    }
  };
  vector<vector<pair<long, long>>> E;
  vector<bool> used;
  size_t V;

 public:
  Prim() : V(0) {}
  Prim(size_t v) : V(v), E(v, vector<pair<long, long>>(0)), used(v, false) {}
  size_t size() { return V; }
  void add_edge_directed(long start, long goal, long weight) {
    E[start].push_back(pair<long, long>(goal, weight));
  }
  void add_edge_undirected(long start, long goal, long weight) {
    E[start].push_back(pair<long, long>(goal, weight));
    E[goal].push_back(pair<long, long>(start, weight));
  }
  long min_spanning_tree(long start) {
    priority_queue<pair<long, long>, vector<pair<long, long>>, Order> mincost;
    long minval = 0;
    mincost.push(pair<long, long>(0, start));
    while (1) {
      if (mincost.empty()) break;
      pair<long, long> node = mincost.top();
      mincost.pop();
      if (used[node.second]) continue;
      minval += node.first;
      used[node.second] = true;
      for (long i = 0; i < (E[node.second].size()); i++) {
        if (!used[E[node.second][i].first])
          mincost.push(pair<long, long>(E[node.second][i].second,
                                        E[node.second][i].first));
      }
    }
    return minval;
  }
};
int main(void) {
  long V, E, r;
  long u, v, w;
  cin >> V >> E >> r;
  Prim prim(V);
  for (long i = 0; i < (E); i++) {
    cin >> u >> v >> w;
    prim.add_edge_directed(u, v, w);
  }
  cout << prim.min_spanning_tree(r) << endl;
  return 0;
}
