using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Edge
    {
        internal int from, to, cost;

        public Edge(int from, int to, int cost)
        {
            this.from = from;
            this.to = to;
            this.cost = cost;
        }
    }

    class Program
    {
        static readonly int INFTY = int.MaxValue;

        static int[] no, prev, mcost;
        static Dictionary<int, List<int>> comp, next;
        static bool[] mark;
        static int cost;
        static bool found;

        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(' ');
            int V = int.Parse(input[0]);
            int E = int.Parse(input[1]);
            int r = int.Parse(input[2]);

            Dictionary<int, List<Edge>> G = new Dictionary<int, List<Edge>>();
            for (int i = 0; i < V; i++) G.Add(i, new List<Edge>());

            for (int i = 0; i < E; i++)
            {
                input = Console.ReadLine().Split(' ');
                int s = int.Parse(input[0]);
                int t = int.Parse(input[1]);
                int w = int.Parse(input[2]);

                G[s].Add(new Edge(s, t, w));
            }

            Console.WriteLine(MinimumSpanningArborescence(G, r));
        }

        static int MinimumSpanningArborescence(Dictionary<int, List<Edge>> G, int r)
        {
            int n = G.Count;

            Dictionary<int, List<Edge>> G_RevEdge = new Dictionary<int, List<Edge>>();
            no = new int[n];
            comp = new Dictionary<int, List<int>>();
            for (int i = 0; i < n; i++)
            {
                G_RevEdge.Add(i, new List<Edge>());
                comp.Add(i, new List<int>());
            }

            for (int i = 0; i < n; i++)
            {
                no[i] = i;
                comp[i].Add(i);

                for (int j = 0; j < G[i].Count; j++)
                {
                    Edge e = G[i][j];
                    G_RevEdge[e.to].Add(e);
                }
            }

            cost = 0;
            while (true)
            {
                prev = Enumerable.Repeat(-1, n).ToArray();
                mcost = Enumerable.Repeat(INFTY, n).ToArray();

                for (int i = 0; i < n; i++)
                {
                    if (i == r) continue;

                    for (int j = 0; j < G_RevEdge[i].Count; j++)
                    {
                        int p = G_RevEdge[i][j].from;

                        if (no[p] != no[i] && G_RevEdge[i][j].cost < mcost[no[i]])
                        {
                            mcost[no[i]] = G_RevEdge[i][j].cost;
                            prev[no[i]] = no[p];
                        }
                    }
                }

                next = new Dictionary<int, List<int>>();
                for (int i = 0; i < n; i++) next.Add(i, new List<int>());

                for (int i = 0; i < n; i++)
                {
                    if (prev[i] >= 0) next[prev[i]].Add(i);
                }

                mark = new bool[n];

                bool stop = true;
                for (int i = 0; i < n; i++)
                {
                    if (i == r || mark[i] || comp[i].Count == 0) continue;

                    found = false;

                    Visit(G_RevEdge, i, i, r);

                    if (found) stop = false;
                }

                if (stop)
                {
                    for (int i = 0; i < n; i++)
                    {
                        if (prev[i] >= 0) cost += mcost[i];
                    }
                    return cost;
                }
            }
        }

        static void Visit(Dictionary<int, List<Edge>> G_RevEdge, int v, int s, int r)
        {
            int n = G_RevEdge.Count;

            if (mark[v])
            {
                int[] temp = new int[n];
                no.CopyTo(temp, 0);

                found = true;

                do
                {
                    cost += mcost[v];
                    v = prev[v];

                    if (v != s)
                    {
                        while (comp[v].Count > 0)
                        {
                            int lastIndex = comp[v].Count - 1;
                            no[comp[v][lastIndex]] = s;
                            comp[s].Add(comp[v][lastIndex]);
                            comp[v].RemoveAt(lastIndex);
                        }
                    }
                } while (v != s);

                for (int k = 0; k < comp[s].Count; k++)
                {
                    int i = comp[s][k];

                    if (i != r)
                    {
                        for (int j = 0; j < G_RevEdge[i].Count; j++)
                        {
                            if (no[G_RevEdge[i][j].from] != s)
                            {
                                G_RevEdge[i][j].cost -= mcost[temp[i]];
                            }
                        }
                    }
                }
            }

            mark[v] = true;
            for (int k = 0; k < next[v].Count; k++)
            {
                int i = next[v][k];

                if (no[i] != no[v] && prev[no[i]] == v)
                {
                    if (!mark[no[i]] || i == s)
                    {
                        Visit(G_RevEdge, i, s, r);
                    }
                }
            }
        }
    }
}

Measured memory_bytes: 10508