#include <bits/stdc++.h>
using namespace std;
class UnionFind {
 public:
  vector<int> par, rank;
  void init(int n) {
    par = vector<int>(n);
    rank = vector<int>(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y]) rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  UnionFind(int n) { init(n); }
  UnionFind() {}
};
long long Prim(vector<vector<pair<int, int> > > graph, int start, int V) {
  priority_queue<pair<int, pair<int, int> >,
                 vector<pair<int, pair<int, int> > >,
                 greater<pair<int, pair<int, int> > > >
      Q;
  UnionFind uf(V);
  long long ans = 0;
  for (int i = (int)(0); i < (int)(graph[start].size()); i++) {
    Q.push(make_pair(graph[start][i].second,
                     make_pair(start, graph[start][i].first)));
  }
  for (int i = (int)(0); i < (int)(V - 1); i++) {
    pair<int, pair<int, int> > edge;
    do {
      edge = Q.top();
      Q.pop();
    } while (uf.same(edge.second.first, edge.second.second));
    ans += edge.first;
    uf.unite(edge.second.first, edge.second.second);
    int to = edge.second.second;
    for (int j = (int)(0); j < (int)(graph[to].size()); j++) {
      Q.push(make_pair(graph[to][j].second, make_pair(to, graph[to][j].first)));
    }
  }
  return ans;
}
int main() {
  int V, E, r;
  cin >> V >> E >> r;
  vector<vector<pair<int, int> > > G(V);
  for (int i = (int)(0); i < (int)(E); i++) {
    int s, t, w;
    cin >> s >> t >> w;
    G[s].push_back(make_pair(t, w));
  }
  cout << Prim(G, r, V) << endl;
  return 0;
}
