3
1 1 5
1 3 42
1 2 42
 2
42 23
1 2 10
 10
45792697 27183921 4791060 77070594 27286110 66957065 19283638 2944837 26775511 65379701
5 8 25
8 10 94
1 4 14
9 7 96
4 2 16
2 6 58
2 3 99
6 8 21
8 9 87
 5
3 1 2 6 5
1 2 3
2 3 1
4 3 9
5 3 1
 10
26 31 21 57 56 44 54 58 79 97
2 1 277
1 8 91
1 7 380
4 1 649
10 5 799
10 1 940
8 6 627
6 3 177
9 6 685
 10
8 100 62 38 26 51 26 23 77 32
6 8 29
4 1 82
7 8 66
7 10 67
8 9 98
6 1 14
1 5 48
3 1 58
2 9 90
 2
23 42
1 2 10
 1
42
 3
1 5 1
1 3 42
1 2 42
 10
1 1 1 1 1 1 1 1 1 1
1 2 5
1 3 5
1 4 5
1 5 5
1 6 5
1 7 5
1 8 5
1 9 5
1 10 5
 3
1 1 1
1 2 42
2 3 42
 3
5 1 1
1 3 42
1 2 24

3 1042.0638260857 1 727.3238618387 6 283959805416.40496826
 3 192.0000000000 1 13952642.4776933547 8 544327.1927847408 2 727.3238618387 1 0.0000000000 2 1042.0638260857 1 100.6230589875 2 544.3822186663 1 389.7666169867
#include <bits\stdc++.h>
using namespace std;
typedef vector<int> Vint;
typedef long long ll;
typedef long double ld;
#define pb push_back
#define mp make_pair

struct edge
{
    int to;
    int cost;
};

struct w_graph
{
    Vint w;
    vector<vector<edge> > graph;
    int n;

    void read (int n_)
    {
        n = n_;
        w.resize(n);
        graph.resize(n);
        for (int i = 0; i < n; i++)
            scanf(" %d", &w[i]);

        int x, y, l;
        for (int i = 1; i < n; i++)
        {
            scanf(" %d %d %d", &x, &y, &l);
            x--;    y--;
            graph[x].pb(edge{y, l});
            graph[y].pb(edge{x, l});
        }
    }

    void dfs (int v, vector<char> &used, Vint &dst)
    {
        used[v] = 1;

        for (const auto &dest : graph[v])
        if (!used[dest.to])
        {
            dst[dest.to] = dst[v] + dest.cost;
            dfs(dest.to, used, dst);
        }
    }

    ld calc (int v)
    {
        Vint dst(n);
        vector<char> used(n, 0);
        dfs(v, used, dst);

        ld ans = 0;
        for (int i = 0; i < n; i++)
            ans += (ld)dst[i] * sqrt((ld)dst[i]) * (ld)w[i];
        return ans;
    }

    void print (int v)
    {
        assert(0 <= v && v < n);
        ld res = calc(v);
        printf("%d %.10f\n", v + 1, (double)res);
    }
};

struct Centroid
{
    vector<Vint> graph;
    int n;
    Vint used;
    Vint subtree;
    Vint pred;
    int timestamp;

    Centroid (const w_graph &g)
    {
        n = g.n;
        graph.resize(n);

        for (int i = 0; i < n; i++)
        for (const auto &dest : g.graph[i])
            graph[i].pb(dest.to);

        timestamp = 0;
    }

    void dfs_sub (int x)
    {
        used[x] = timestamp;
        subtree[x] = 1;

        for (int dest : graph[x])
        if (used[dest] != timestamp)
        {
            pred[dest] = x;
            used[dest] = timestamp;
            dfs_sub (dest);
            subtree[x] += subtree[dest];
        }
    }

    vector<Vint> work (Vint &who)
    {
        vector<Vint> result(n);
        used.assign(n, 0);
        subtree.assign(n, 0);
        pred.assign(n, -1);
        who.assign(n, -1);

        deque<pair<int, int> > all;
        all.push_back(mp(0, -1));

        while (!all.empty())
        {
            int curtree = all.front().first;
            int cpred = all.front().second;
            all.pop_front();

            int v = center(curtree);
            who[curtree] = v;

            if (cpred != -1)
            {
                result[cpred].pb(v);
            }

            for (int u : graph[v])
            {
                auto it = find(graph[u].begin(), graph[u].end(), v);
                assert (it != graph[u].end());
                graph[u].erase(it);
                all.push_back(mp(u, v));
            }
        }

        return result;
    }

    int center (int v)
    {
        timestamp++;
        pred[v] = -1;
        dfs_sub(v);

        while (true)
        {
            int cur_sz = subtree[v] / 2;

            int total = 0;
            bool ok = false;

            for (int dest : graph[v])
            if (dest != pred[v])
            {
                int cur = subtree[dest];
                if (cur > cur_sz)
                {
                    v = dest;
                    ok = true;
                    break;
                }
                total += cur;
            }

            if (!ok)
            {
                if (subtree[v] - 1 - total <= cur_sz)
                    return v;
                else
                    v = pred[v];
            }
        }
    }
};

struct Grad
{
    vector<Vint> decom;
    w_graph g;
    Vint who;
    int n;
    const ld eps = 1e-6;

    Grad (const w_graph &g_, const vector<Vint> &decom_,
          const Vint &who_)
    {
        g = g_;
        decom = decom_;
        who = who_;
        n = (int)decom.size();
    }

    void dfs (int x, vector<char> &used, vector<ld> &subtree, ld dst)
    {
        used[x] = 1;
        subtree[x] = g.w[x] * sqrt(dst);

        for (const auto &dest : g.graph[x])
        if (!used[dest.to])
        {
            dfs(dest.to, used, subtree, dst + dest.cost);
            subtree[x] += subtree[dest.to];
        }
    }

    Vint go (int root)
    {
        Vint ans;

        while (true)
        {
            bool again = false;

            for (int i = max((int)ans.size() - 2, 0); i < (int)ans.size(); i++)
            if (ans[i] == root)
            {
                again = true;
                break;
            }

            if (again)
                break;

            if (root == -1)
                break;
            ans.pb(root);

            vector<ld> subtree_der_sum(n);
            vector<char> used(n);
            dfs(root, used, subtree_der_sum, 0);

            ld total_sum = 0;
            auto &edges = g.graph[root];
            for (const auto &x : edges)
                total_sum += subtree_der_sum[x.to];

            bool ok = false;
            for (const auto &x : edges)
            {
                ld cur_sum = total_sum - 2 * subtree_der_sum[x.to];
                if (cur_sum < -eps)
                {
                    root = who[x.to];
                    ok = true;
                    break;
                }
            }

            if (!ok)
                break;
        }

        return ans;
    }
};

void solve (int n)
{
    w_graph g;
    g.read(n);

    Vint who;
    vector<Vint> decomp = Centroid(g).work(who);

    int root = -1;
    Vint parent(n, -1);
    for (int i = 0; i < n; i++)
    for (int x : decomp[i])
        parent[x] = i;

    for (int i = 0; i < n; i++)
    if (parent[i] == -1)
    {
        assert(root == -1);
        root = i;
    }
    assert(root != -1);

    Vint path = Grad(g, decomp, who).go(root);

    assert(!path.empty());
    pair<ld, int> ans(1e100, -1);
    for (int i = max((int)path.size() - 4, 0); i < (int)path.size(); i++)
        ans = min(ans, pair<ld, int>(g.calc(path[i]), path[i]));

    g.print(ans.second);
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "w", stdout);
    #endif // ONLINE_JUDGE

    int n;
    while (cin >> n)
        solve(n);
}
