#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define int long long

using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

signed main()
{
    ios_base::sync_with_stdio(false);
//    cin.tie(0);
    int n; cin >> n;
    vector<ll> potrebnoboje(n);
    for(int i = 0; i < n; i++) cin >> potrebnoboje[i];
    vector< vector<int> > g(n, vector<int>());
    int u, v;
    for(int i = 1; i < n; i++){
        cin >> u >> v;
        u--; v--;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    vector<bool> granicniCvor(n);
    int startni = 0;
    for(int i = 0; i < n; i++){
        if(g[i].size() == 1){
            granicniCvor[ g[i][0] ] = 1;
        }else{
            startni = i;
        }
    }
    queue<pair<int, bool>> bfs;

    // obilazak parnih mesta
    vector<bool> poseceni(n);
    set<int> rezParni;
    set<int> rezParniPrim;
    bfs.emplace(startni, 1);
    ll parnaSum = 0; // startni je ukljucen
    while(!bfs.empty()){
        int curr;
        bool parnost;
        tie(curr, parnost) = bfs.front();
        bfs.pop();
        if(poseceni[curr]) continue;
        poseceni[curr] = 1;
//        cout << "c" << curr << " " << parnost << endl;
        if(parnost){
            parnaSum += potrebnoboje[curr];
            rezParni.insert(curr);
        }else if(granicniCvor[curr]){
            ll sum = 0;
            for(int cvor : g[curr]){
                if(g[cvor].size() == 1){
                    sum += potrebnoboje[cvor];
                }
            }
            if(sum > potrebnoboje[curr]){
//                cout << "Granicni " << curr << endl;
                for(int cvor : g[curr]){
                    if(g[cvor].size() == 1){
                        poseceni[cvor] = 1;
                    }
                }
                rezParniPrim.insert(curr);
                parnaSum += potrebnoboje[curr];
            }
        }
        for(int cvor : g[curr]){
            bfs.emplace(cvor, !parnost);
        }
    }

    //obilazak neparnih mesta
    poseceni = vector<bool>(n, 0);
    set<int> rezNeparni;
    set<int> rezNeparniPrim;
    bfs.emplace(startni, 0);
    ll neparnaSum = 0; // startni NIje ukljucen
    while(!bfs.empty()){
        int curr;
        bool parnost;
        tie(curr, parnost) = bfs.front();
        bfs.pop();
        if(poseceni[curr]) continue;
        poseceni[curr] = 1;
//        cout << "c" << curr << " " << parnost << endl;
        if(parnost){
            neparnaSum += potrebnoboje[curr];
            rezNeparni.insert(curr);
        }else if(granicniCvor[curr]){
            ll sum = 0;
            for(int cvor : g[curr]){
                if(g[cvor].size() == 1){
                    sum += potrebnoboje[cvor];
                }
            }
            if(sum > potrebnoboje[curr]){
//                cout << "Granicni " << curr << endl;
                for(int cvor : g[curr]){
                    if(g[cvor].size() == 1){
                        poseceni[cvor] = 1;
                    }
                }
                rezNeparniPrim.insert(curr);
                neparnaSum += potrebnoboje[curr];
            }
        }
        for(int cvor : g[curr]){
            bfs.emplace(cvor, !parnost);
        }
    }

    cout << min(parnaSum, neparnaSum) << "\n";
    if(parnaSum < neparnaSum){
        cout << rezParni.size() << "\n";
        for(int x : rezParni) cout << x+1 << " "; cout << "\n";

        cout << rezParniPrim.size() << "\n";
        for(int x : rezParniPrim) cout << x+1 << " "; cout << "\n";
    }else{
        cout << rezNeparni.size() << "\n";
        for(int x : rezNeparni) cout << x+1 << " "; cout << "\n";

        cout << rezNeparniPrim.size() << "\n";
        for(int x : rezNeparniPrim) cout << x+1 << " "; cout << "\n";
    }
}