#include <bits/stdc++.h>
using namespace std;
class Union_Find {
 private:
  vector<int> p, r;
  int find(int x) {
    if (p[x] == x)
      return x;
    else
      return p[x] = find(p[x]);
  }

 public:
  Union_Find(int N) {
    p.resize(N);
    r.resize(N);
    for (int i = 0; i < (int)N; i++) {
      p[i] = i;
      r[i] = 0;
    }
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (r[x] < r[y])
      p[x] = y;
    else {
      p[y] = x;
      if (r[x] == r[y]) r[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};
class GraphCLE {
 private:
  struct node {
    long long int d;
    int edgeid;
    set<int> inc;
  };
  vector<node> nodes;
  struct edgeinfo {
    int from, to, cost;
  };
  struct edge {
    vector<edgeinfo> info;
    int mode;
  };
  vector<edge> edges;
  int n;
  void reset() {}
  void contract(set<int> pack, int p, Union_Find *uf) {
    int newnodeid = nodes.size();
    nodes.push_back({(long long)1e14, -1, pack});
    for (int i = 0; i < (int)edges.size(); i++) {
      edgeinfo buf = edges[i].info.back();
      if ((*uf).same(buf.from, p)) {
        if ((*uf).same(buf.to, p)) {
          if (edges[i].mode == 1)
            edges[i].mode = 2;
          else
            edges[i].mode = -1;
        } else
          edges[i].info.push_back({newnodeid, buf.to, buf.cost});
      } else if ((*uf).same(buf.to, p)) {
        int x = buf.cost - edges[nodes[buf.to].edgeid].info.back().cost;
        edges[i].info.push_back({buf.from, newnodeid, x});
        if (x < nodes.back().d) {
          nodes.back().d = x;
          nodes.back().edgeid = i;
        }
      }
    }
    edgeinfo buf = edges[nodes.back().edgeid].info.back();
    edges[nodes.back().edgeid].mode = 1;
    (*uf).unite(buf.from, buf.to);
    return;
  }
  void unfold() {
    while (nodes.size() > n) {
      edges[nodes.back().edgeid].info.pop_back();
      int flag = edges[nodes.back().edgeid].info.back().to;
      auto itr = nodes.back().inc.begin();
      for (int i = 0; i < (int)nodes.back().inc.size(); i++) {
        edgeinfo buf = edges[nodes[*itr].edgeid].info.back();
        if (buf.to == flag)
          edges[nodes[*itr].edgeid].mode = -1;
        else
          edges[nodes[*itr].edgeid].mode = 1;
        itr++;
      }
      nodes.pop_back();
    }
  }

 public:
  vector<long long int> result;
  GraphCLE(vector<vector<pair<int, int>>> data) {
    n = data.size();
    result.resize(n);
    nodes.resize(n);
    for (int i = 0; i < (int)n; i++) {
      nodes[i] = {(long long)1e14, -1, {}};
      for (int j = 0; j < (int)data[i].size(); j++) {
        edgeinfo buf = {i, data[i][j].first, data[i][j].second};
        edges.push_back({{buf}, 0});
      }
    }
  }
  void mainfunc(int start) {
    nodes[start].d = 0;
    for (int i = 0; i < (int)edges.size(); i++) {
      edgeinfo buf = edges[i].info.back();
      if (buf.to == start) continue;
      if (buf.cost < nodes[buf.to].d) {
        nodes[buf.to].d = buf.cost;
        nodes[buf.to].edgeid = i;
      }
    }
    Union_Find uf(n * 2);
    for (int i = 0; i < (int)n; i++) {
      if (i == start) continue;
      edgeinfo buf = edges[nodes[i].edgeid].info.back();
      edges[nodes[i].edgeid].mode = 1;
      uf.unite(buf.from, buf.to);
    }
    while (true) {
      int p = -1;
      set<int> pack;
      for (int i = 0; i < (int)nodes.size(); i++) {
        if (uf.same(i, start))
          continue;
        else if (p == -1) {
          p = i;
          pack.insert(i);
        } else if (uf.same(i, p))
          pack.insert(i);
      }
      if (p == -1) {
        unfold();
        for (int i = 0; i < (int)n; i++) result[i] = nodes[i].d;
        break;
      }
      contract(pack, p, &uf);
      auto itr = pack.begin();
      for (int i = 0; i < (int)pack.size(); i++) {
        uf.unite(*itr, start);
        itr++;
      }
    }
  }
};
int main() {
  int n, m, r;
  cin >> n >> m >> r;
  vector<vector<pair<int, int>>> data(n);
  for (int i = 0; i < (int)m; i++) {
    int s, t, d;
    cin >> s >> t >> d;
    data[s].push_back({t, d});
  }
  GraphCLE cle(data);
  cle.mainfunc(r);
  long long int ans = 0;
  for (int i = 0; i < (int)n; i++) {
    ans += cle.result[i];
  }
  cout << ans << endl;
  return 0;
}
