Problem:
AYBABTU
There is a tree that has
n
nodes and
n-1
edges.
There are military bases on
t
out of the
n
nodes.
We want to  disconnect the bases as  much as possible by destroying
k
edges.
The tree will  be split into
k+1
regions when we destroy
k
edges.
Given the purpose to disconnect the bases, we only consider to split in a way that each of these
k+1
regions  has at least one base.
When we destroy an edge, we must pay destroying cost.
Find the minimum destroying cost to split  the tree.
Input
The input consists of multiple data sets.
Each data set has the following format.
The first line  consists of three integers
n
,
t
, and
k
(
1 \leq n \leq 10,000
,
1 \leq t \leq n
,
0 \leq k \leq t-1
).
Each of the next
n-1
lines  consists of three integers representing an edge.
The first two integers represent node numbers connected  by the edge.
A node number is a positive integer less than or equal to
n
.
The last one integer represents destroying cost.
Destroying cost is a non-negative integer less than or equal to 10,000.
The next
t
lines  contain a distinct list of integers one  in each line,  and represent  the list of nodes with bases.
The input ends with a line containing three zeros, which should not be processed.
Output
For each test case, print its case number and the minimum destroying cost to split  the tree with the case number.
Sample Input
2 2 1
1 2 1
1
2
4 3 2
1 2 1
1 3 2
1 4 3
2
3
4
0 0 0
Output for the Sample Input
Case 1: 1
Case 2: 3

Submitted solutions:

code_snippet: /*
 * =====================================================================================
 *
 *       Filename:  j.cpp
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  2013年11月23日 14时47分56秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  NONO (),
 *   Organization:
 *
 * =====================================================================================
 */

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#define INF 0x3f3f3f3f
#define er(i) (1<<i)
#define lb lower_bound
#define up upper_bound
#define eps 1e-8
#define mp make_pair
#define pii pair<int, int>
#define zero(x) (((x)>0?(x):-(x))<eps)
#define mem(a,b) memset((a),(b),sizeof((a)))
#define lld long long

using namespace std;

struct s{
    int a, b;
    int cost;
}num[10009];

int n, t, k;
int fa[10009];
int cnt[10009];

int getfa(int a) {
    if(fa[a] == a) return a;
    return fa[a] = getfa(fa[a]);
}

bool cmp(s a, s b) {
    return a.cost > b.cost;
}

int main() {

//#ifndef ONLINE_JUDGE
//    freopen("F:/ACMData.txt","r",stdin);
//#endif

    int cc = 1;
    while(~scanf("%d%d%d", &n, &t, &k)) {
        if(n == 0 && t == 0 && k == 0) break;
        for(int i = 1; i <= n; i++) {
            cnt[i] = 0;
            fa[i] = i;
        }
        for(int i = 0; i < n - 1; i++) {
            scanf("%d%d%d", &num[i].a, &num[i].b, &num[i].cost);
        }
        int a;
        for(int i = 0; i < t; i++) {
            scanf("%d", &a);
            cnt[a] = 1;
        }
        sort(num, num + n - 1, cmp);
        int cnt1 = t;
        int ans = 0;
        for(int i = 0; i < n - 1; i++) {
            int ffa = getfa(num[i].a);
            int ffb = getfa(num[i].b);
            if(cnt[ffa] != 0 && cnt[ffb] != 0) {
                if(cnt1 <= k + 1) {
                    ans += num[i].cost;
                } else {
                    cnt1--;
                    fa[ffa] = ffb;
                    cnt[ffb] += cnt[ffa];
                }
            } else {
                fa[ffa] = ffb;
                cnt[ffb] += cnt[ffa];
            }
        }
        printf("Case %d: %d\n", cc++, ans);
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3660
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct UnionFind{
    vector<int> par; int n;
    vector<bool> base;
    UnionFind(){}
    UnionFind(int _n):par(_n,-1),n(_n),base(_n,false){}
    int root(int x){return par[x]<0?x:par[x]=root(par[x]);}
    bool same(int x,int y){return root(x)==root(y);}
    int size(int x){return -par[root(x)];}
    bool getbase(int x){return base[root(x)];}
    bool unite(int x,int y){
        x=root(x),y=root(y); if(x==y)return false;
        if(size(x)>size(y))swap(x,y);
        base[y] = base[x] || base[y]; par[y]+=par[x]; par[x]=y; n--; return true;
    }
};

/**
 * @brief Union Find
 */

int main() {
    int _ = 0;
while(1) {
    _++;
    int N, T, K;
    cin >> N >> T >> K;
    if (N == 0) return 0;
    vector<int> A(N-1), B(N-1), C(N-1);
    rep(i,0,N-1) {
        cin >> A[i] >> B[i] >> C[i];
        A[i]--, B[i]--;
    }
    vector<int> ord(N-1);
    iota(ALL(ord),0);
    sort(ALL(ord), [&](int i, int j){return C[i] > C[j];});
    UnionFind UF(N);
    rep(i,0,T) {
        int X;
        cin >> X;
        X--;
        UF.base[X] = true;
    }
    vector<int> V;
    for (int i : ord) {
        if (UF.getbase(A[i]) && UF.getbase(B[i])) V.push_back(C[i]);
        else UF.unite(A[i],B[i]);
    }
    sort(ALL(V));
    int ANS = 0;
    rep(i,0,K) ANS += V[i];
    cout << "Case " << _ << ": " << ANS << endl;
}
}
accuracy: 1
time_ms: 110
memory_kb: 3632
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct UnionFind {
  int n;
  vector<int> par;
  vector<int> siz;
  
  UnionFind() = default;
  UnionFind(int _n) : n(_n), par(_n), siz(_n, 0) {
    for (int i = 0; i < n; ++i) par[i] = i;
  }
  
  void set(int x) {
    siz[x] = 1;
  }
  
  int root(int x) {
    if (par[x] == x) return x;
    else return par[x] = root(par[x]);
  }
  
  bool same(int x, int y) {
    return root(x) == root(y);
  }
  
  bool update(int x, int y) {
    int rx = root(x), ry = root(y);
    if (rx == ry) return false;
    return siz[rx] && siz[ry];
  }
  
  void merge(int x, int y) {
    int rx = root(x), ry = root(y);
    if (rx == ry) return;
    bool flg = update(rx, ry);
    siz[rx] += siz[ry];
    if (flg) siz[rx]--;
    par[ry] = rx;
    return;
  }
  
};

void output(int num, long long res) {
  cout << "Case" << " " << num << ":" << " " << res << endl;
  return;
}

bool is_end = false;

void solve(int num) {
  int N, T, K; cin >> N >> T >> K;
  if (N + T + K == 0) {
    is_end = true;
    return;
  }
  
  vector<array<int, 3>> edge;
  for (int i = 0; i < N-1; ++i) {
    int u, v, w; cin >> u >> v >> w;
    u--, v--;
    edge.push_back({w, u, v});
  }
  sort(edge.begin(), edge.end());
  reverse(edge.begin(), edge.end());
  
  UnionFind uf(N);
  for (int t = 0; t < T; ++t) {
    int u; cin >> u;
    u--;
    uf.set(u);
  }
  
  long long res = 0;
  int cnt = 0;
  for (auto [w, u, v] : edge) {
    if (uf.update(u, v)) {
      // cout << u << " " << v << endl;
      if (cnt >= T - K - 1) res += w;
      cnt++;
    }
    uf.merge(u, v);
  }
  output(num, res);
  
  return;
}

int main() {
  int num = 1;
  while (!is_end) {
    solve(num);
    num++;
  }
  
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3712
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < (n); i++)
#define per(i, n) for (int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for (int i = (l); i < (r); i++)
#define per2(i, l, r) for (int i = (r)-1; i >= (l); i--)
#define each(e, x) for (auto &e : x)
#define eb emplace_back
#define sz(x) (int)x.size()

using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;

const int inf = (1 << 29) - 1;

template <typename T>
bool chmin(T &x, T y) {
    return x > y ? (x = y, true) : false;
}

int main() {
    for (int t = 1;; t++) {
        int N, T, K;
        cin >> N >> T >> K;
        if (N == 0) break;

        vector<vector<pii>> es(N);

        rep(i, N - 1) {
            int u, v, w;
            cin >> u >> v >> w;
            u--, v--;
            es[u].eb(v, w);
            es[v].eb(u, w);
        }

        vector<int> c(N, 0);

        rep(i, T) {
            int u;
            cin >> u;
            u--;
            c[u] = 1;
        }

        auto dfs = [&](auto &&dfs, int now, int pre = -1) -> vector<vector<int>> {
            vector<vector<int>> dp(2, vector<int>(1, inf));
            dp[c[now]][0] = 0;
            for (auto [e, w] : es[now]) {
                if (e == pre) continue;
                auto tmp = dfs(dfs, e, now);
                int X = sz(dp[0]), Y = sz(tmp[0]);
                vector<vector<int>> ndp(2, vector<int>(X + Y, inf));
                rep(i, 2) rep(j, 2) {
                    rep(k, X) rep(l, Y) chmin(ndp[i | j][k + l], dp[i][k] + tmp[j][l]);
                    if (j == 1) {
                        rep(k, X) rep(l, Y) chmin(ndp[i][k + l + 1], dp[i][k] + tmp[j][l] + w); //
                    }
                }
                swap(dp, ndp);
            }
            return dp;
        };

        auto dp = dfs(dfs, 0);

        cout << "Case " << t << ": " << dp[1][K] << '\n';
    }
}
accuracy: 1
time_ms: 6990
memory_kb: 7224
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T>
bool chmax(T& a, const T& b) {
    return a < b ? (a = b, 1) : 0;
}
template <typename T>
bool chmin(T& a, const T& b) {
    return a > b ? (a = b, 1) : 0;
}

class UnionFind {
   public:
    UnionFind() = default;
    explicit UnionFind(int n) : data(n, -1) {}

    int find(int x) {
        if (data[x] < 0) return x;
        return data[x] = find(data[x]);
    }

    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (data[x] > data[y]) std::swap(x, y);
        data[x] += data[y];
        data[y] = x;
    }

    bool same(int x, int y) { return find(x) == find(y); }

    int size(int x) { return -data[find(x)]; }

   private:
    std::vector<int> data;
};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int q = 1;
    while (true) {
        int n, t, k;
        cin >> n >> t >> k;
        if (n == 0) break;
        ll ans = 0;
        vector<tuple<int, int, ll>> edges(n - 1);
        rep(i, 0, n - 1) {
            int u, v, w;
            cin >> u >> v >> w;
            --u, --v;
            ans += w;
            edges[i] = {u, v, w};
        }
        vector<bool> base(n);
        int cnt = t;
        rep(_, 0, t) {
            int x;
            cin >> x;
            --x;
            base[x] = true;
        }

        sort(all(edges),
             [&](auto& e1, auto& e2) { return get<2>(e1) > get<2>(e2); });

        UnionFind uf(n);

        for (auto [u, v, w] : edges) {
            bool ba = base[uf.find(u)] && base[uf.find(v)];
            bool bo = base[uf.find(u)] || base[uf.find(v)];
            if (ba && cnt - 1 < k + 1) {
                // skip
            } else {
                uf.unite(u, v);
                base[uf.find(u)] = bo;
                ans -= w;
                if (ba) --cnt;
            }
        }

        cout << "Case " << q << ": " << ans << "\n";
        ++q;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3568
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)
#define revrep(i, t, s) for (int i = (int)(t)-1; i >= (int)(s); --i)
#define all(x) begin(x), end(x)
template <typename T>
bool chmax(T& a, const T& b) {
    return a < b ? (a = b, 1) : 0;
}
template <typename T>
bool chmin(T& a, const T& b) {
    return a > b ? (a = b, 1) : 0;
}

template <typename M, typename O,
          typename M::T (*act)(typename M::T, typename O::T)>
class EulerTourTree {
    using T = typename M::T;
    using E = typename O::T;

   public:
    EulerTourTree() = default;
    explicit EulerTourTree(int n) {
        ptr.resize(n);
        for (int i = 0; i < n; ++i) {
            ptr[i][i] = std::make_shared<Node>(i, i);
        }
    }

    void link(int u, int v) {
        assert(!same(u, v));
        auto tu = reroot(get_node(u, u));
        auto tv = reroot(get_node(v, v));
        join(join(tu, get_node(u, v)), join(tv, get_node(v, u)));
    }

    void cut(int u, int v) {
        assert(ptr[u].find(v) != ptr[u].end());
        node_ptr a, b, c;
        std::tie(a, b, c) = split(get_node(u, v), get_node(v, u));
        join(a, c);
        ptr[u].erase(v);
        ptr[v].erase(u);
    }

    bool same(int u, int v) { return same(get_node(u, u), get_node(v, v)); }

    T get(int v) {
        auto t = get_node(v, v);
        splay(t);
        return t->val;
    }

    void update(int v, const T& x) {
        auto t = get_node(v, v);
        splay(t);
        t->val = x;
        recalc(t);
    }

    void update(int v, int p, const E& x) {
        cut(p, v);
        auto t = get_node(v, v);
        splay(t);
        t->lazy = O::op(t->lazy, x);
        link(p, v);
    }

    T fold(int v, int p = -1) {
        if (p != -1) cut(p, v);
        auto t = get_node(v, v);
        splay(t);
        T ret = t->sum;
        if (p != -1) link(p, v);
        return ret;
    }

   private:
    struct Node;
    using node_ptr = std::shared_ptr<Node>;

    struct Node {
        node_ptr ch[2] = {nullptr, nullptr};
        node_ptr par = nullptr;
        int from, to, sz;
        T val = M::id(), sum = M::id();
        E lazy = O::id();
        Node(int from, int to) : from(from), to(to), sz(from == to) {}
    };

    std::vector<std::unordered_map<int, node_ptr>> ptr;

    node_ptr get_node(int u, int v) {
        if (ptr[u].find(v) == ptr[u].end())
            ptr[u][v] = std::make_shared<Node>(u, v);
        return ptr[u][v];
    }

    static node_ptr root(node_ptr t) {
        if (!t) return nullptr;
        while (t->par) t = t->par;
        return t;
    }

    static bool same(node_ptr s, node_ptr t) {
        if (s) splay(s);
        if (t) splay(t);
        return root(s) == root(t);
    }

    static node_ptr reroot(node_ptr t) {
        auto s = split(t);
        return join(s.second, s.first);
    }

    // splay tree

    static int size(const node_ptr& t) { return t ? t->sz : 0; }

    static node_ptr recalc(const node_ptr& t) {
        if (!t) return t;
        t->sz = size(t->ch[0]) + (t->from == t->to) + size(t->ch[1]);
        t->sum = t->val;
        if (t->ch[0]) t->sum = M::op(t->ch[0]->sum, t->sum);
        if (t->ch[1]) t->sum = M::op(t->sum, t->ch[1]->sum);
        return t;
    }

    static void push(const node_ptr& t) {
        if (t->lazy != O::id()) {
            t->val = act(t->val, t->lazy);
            if (t->ch[0]) {
                t->ch[0]->lazy = O::op(t->ch[0]->lazy, t->lazy);
                t->ch[0]->sum = act(t->ch[0]->sum, t->lazy);
            }
            if (t->ch[1]) {
                t->ch[1]->lazy = O::op(t->ch[1]->lazy, t->lazy);
                t->ch[1]->sum = act(t->ch[1]->sum, t->lazy);
            }
            t->lazy = O::id();
        }
        recalc(t);
    }

    static node_ptr join(node_ptr l, node_ptr r) {
        if (!l) return r;
        if (!r) return l;
        while (l->ch[1]) l = l->ch[1];
        splay(l);
        l->ch[1] = r;
        r->par = l;
        return recalc(l);
    }

    static std::pair<node_ptr, node_ptr> split(node_ptr t) {
        splay(t);
        auto s = t->ch[0];
        t->ch[0] = nullptr;
        if (s) s->par = nullptr;
        return {s, recalc(t)};
    }

    static std::pair<node_ptr, node_ptr> split2(node_ptr t) {
        splay(t);
        auto l = t->ch[0];
        auto r = t->ch[1];
        t->ch[0] = nullptr;
        if (l) l->par = nullptr;
        t->ch[1] = nullptr;
        if (r) r->par = nullptr;
        return {l, r};
    }

    static std::tuple<node_ptr, node_ptr, node_ptr> split(node_ptr s,
                                                          node_ptr t) {
        node_ptr a, b, c, d;
        std::tie(a, b) = split2(s);
        if (same(a, t)) {
            std::tie(c, d) = split2(t);
            return {c, d, b};
        } else {
            std::tie(c, d) = split2(t);
            return {a, c, d};
        }
    }

    static void rotate(node_ptr t, bool b) {
        node_ptr p = t->par, g = p->par;
        p->ch[1 - b] = t->ch[b];
        if (p->ch[1 - b]) t->ch[b]->par = p;
        t->ch[b] = p;
        p->par = t;
        recalc(p);
        recalc(t);
        t->par = g;
        if (t->par) {
            if (g->ch[0] == p)
                g->ch[0] = t;
            else
                g->ch[1] = t;
            recalc(g);
        }
    }

    static void splay(node_ptr t) {
        push(t);
        while (t->par) {
            auto p = t->par, g = p->par;
            if (!g) {
                push(p);
                push(t);
                rotate(t, p->ch[0] == t);
            } else {
                push(g);
                push(p);
                push(t);
                bool b = g->ch[0] == p;
                if (p->ch[1 - b] == t) {
                    rotate(p, b);
                    rotate(t, b);
                } else {
                    rotate(t, 1 - b);
                    rotate(t, b);
                }
            }
        }
    }
};

struct AddMonoid {
    using T = int;
    static T id() { return 0; }
    static T op(T a, T b) { return a + b; }
};

int act(int a, int b) { return a + b; }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int q = 1;
    while (true) {
        int n, t, k;
        cin >> n >> t >> k;
        if (n == 0) break;
        vector<tuple<int, int, ll>> edges(n - 1);
        EulerTourTree<AddMonoid, AddMonoid, act> et(n);
        rep(i, 0, n - 1) {
            int u, v, w;
            cin >> u >> v >> w;
            --u, --v;
            et.link(u, v);
            edges[i] = {u, v, w};
        }
        rep(_, 0, t) {
            int x;
            cin >> x;
            --x;
            et.update(x, 1);
        }

        sort(all(edges),
             [&](auto& e1, auto& e2) { return get<2>(e1) < get<2>(e2); });

        ll ans = 0;
        int rem = k;

        for (auto [u, v, w] : edges) {
            if (rem == 0) break;

            et.cut(u, v);
            if (et.fold(u) == 0 || et.fold(v) == 0) {
                et.link(u, v);
            } else {
                --rem;
                ans += w;
            }
        }

        cout << "Case " << q << ": " << ans << "\n";
        ++q;
    }
}
accuracy: 1
time_ms: 430
memory_kb: 63632
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <tuple>
#include <algorithm>
using namespace std;

class UnionFind {
	public:
	vector<int> par;
	vector<bool> Important;
	
	void init(int sz) {
		par.resize(sz, -1);
		Important.resize(sz, false);
	}
	
	int root(int pos) {
		if (par[pos] == -1) return pos;
		par[pos] = root(par[pos]);
		return par[pos];
	}
	
	void unite(int u, int v) {
		u = root(u);
		v = root(v);
		par[u] = v;
		if (Important[u] == true) Important[v] = true;
	}
	
	bool IsImportant(int u) {
		u = root(u);
		return Important[u];
	}
};

int N, T, K;
int A[100009], B[100009], C[100009];

int main() {
	for (int testcase = 1; testcase <= 869120; testcase++) {
		// Input
		cin >> N >> T >> K; if (N+T+K == 0) break;
		for (int i = 1; i <= N-1; i++) cin >> A[i] >> B[i] >> C[i];
		UnionFind UF; UF.init(N + 2);
		for (int i = 1; i <= T; i++) {
			int idx; cin >> idx;
			UF.Important[idx] = true;
		}
		
		// Solve
		vector<tuple<int, int, int>> tup;
		int Answer = 0;
		for (int i = 1; i <= N - 1; i++) tup.push_back(make_tuple(C[i], A[i], B[i]));
		for (int i = 1; i <= N - 1; i++) Answer += C[i];
		sort(tup.begin(), tup.end());
		reverse(tup.begin(), tup.end());
		
		// Solve 2
		int rem = T - (K+1);
		for (int i = 0; i < (int)tup.size(); i++) {
			int pos1 = get<1>(tup[i]);
			int pos2 = get<2>(tup[i]);
			if (UF.IsImportant(pos1) == true && UF.IsImportant(pos2) == true) {
				if (rem >= 1) {
					UF.unite(pos1, pos2);
					rem -= 1;
					Answer -= get<0>(tup[i]);
				}
			}
			else {
				UF.unite(pos1, pos2);
				Answer -= get<0>(tup[i]);
			}
		}
		
		// Output
		cout << "Case " << testcase << ": " << Answer << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3648
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N, T, K;
int A[10009], B[10009], C[10009];
bool IsBase[10009];
vector<pair<int, int>> G[10009];

void Initialize() {
	for (int i = 0; i < 10009; i++) {
		IsBase[i] = false;
		G[i].clear();
	}
}

pair<vector<int>, vector<int>> dfs(int pos, int pre, int cost) {
	vector<vector<int>> DP1;
	vector<vector<int>> DP2;
	vector<int> H;
	
	// DFS
	int sz = 0;
	for (int i = 0; i < (int)G[pos].size(); i++) {
		int to = G[pos][i].first;
		int val = G[pos][i].second;
		if (to == pre) continue;
		pair<vector<int>, vector<int>> ret = dfs(to, pos, val);
		sz += ret.first.size() - 1;
		DP1.push_back(ret.first);
		DP2.push_back(ret.second);
		H.push_back(to);
	}
	
	// Define Arrays
	vector<int> Val1(sz + 2, (1 << 30));
	vector<int> Val2(sz + 2, (1 << 30));
	
	// Calculate Pattern1
	vector<int> tmp1;
	for (int i = 0; i < (int)H.size(); i++) {
		for (int j = 1; j < (int)DP1[i].size(); j++) {
			int val1 = min(DP1[i][j - 0], DP2[i][j - 0]);
			int val2 = min(DP1[i][j - 1], DP2[i][j - 1]);
			if (val1 == (1 << 30)) break;
			tmp1.push_back(val1 - val2);
		}
	}
	sort(tmp1.begin(), tmp1.end());
	
	// Update Pattern1
	Val1[0] = min(Val1[0], 0);
	if (IsBase[pos] == true) {
		Val2[0] = min(Val2[0], 0);
		if (pre != -1) Val1[1] = min(Val1[1], cost);
	}
	int sum1 = 0;
	for (int i = 0; i < (int)tmp1.size(); i++) {
		sum1 += tmp1[i];
		Val1[i + 1] = min(Val1[i + 1], sum1);
		if (IsBase[pos] == true) {
			Val2[i + 1] = min(Val2[i + 1], sum1);
			if (pre == -1) continue;
			Val1[i + 2] = min(Val1[i + 2], sum1 + cost);
		}
	}
	
	// Calculate Pattern2
	if (IsBase[pos] == false) {
		for (int t = 0; t < (int)H.size(); t++) {
			if (DP2[t][0] == (1 << 30)) continue;
			vector<int> tmp2;
			for (int i = 0; i < (int)H.size(); i++) {
				for (int j = 1; j < (int)DP1[i].size(); j++) {
					int val1 = DP2[i][j - 0];
					int val2 = DP2[i][j - 1];
					if (i != t) val1 = min(val1, DP1[i][j - 0]);
					if (i != t) val2 = min(val2, DP1[i][j - 1]);
					if (val1 == (1 << 30)) break;
					tmp2.push_back(val1 - val2);
				}
			}
			sort(tmp2.begin(), tmp2.end());
			int sum = 0;
			Val1[0] = min(Val1[0], 0);
			Val2[0] = min(Val2[0], 0);
			if (pre != -1) Val1[1] = min(Val1[1], cost);
			for (int i = 0; i < (int)tmp2.size(); i++) {
				sum += tmp2[i];
				Val1[i + 1] = min(Val1[i + 1], sum);
				Val2[i + 1] = min(Val2[i + 1], sum);
				if (pre == -1) continue;
				Val1[i + 2] = min(Val1[i + 2], sum + cost);
			}
		}
	}
	
	/*cout << pos << ":" << endl;
	cout << "   Val1 = {"; for (int i = 0; i < (int)Val1.size(); i++) { if (i) cout << ", "; cout << Val1[i]; } cout << "}" << endl;
	cout << "   Val2 = {"; for (int i = 0; i < (int)Val2.size(); i++) { if (i) cout << ", "; cout << Val2[i]; } cout << "}" << endl;
	cout << endl;*/
	return make_pair(Val1, Val2);
}

int main() {
	for (int testcase = 1; testcase <= 869120; testcase++) {
		Initialize();
		
		// Input
		cin >> N >> T >> K; if (N + T + K == 0) break;
		for (int i = 1; i <= N - 1; i++) {
			cin >> A[i] >> B[i] >> C[i];
			G[A[i]].push_back(make_pair(B[i], C[i]));
			G[B[i]].push_back(make_pair(A[i], C[i]));
		}
		for (int i = 1; i <= T; i++) {
			int idx; cin >> idx;
			IsBase[idx] = true;
		}
		
		// Solve
		pair<vector<int>, vector<int>> Answer = dfs(1, -1, 0);
		cout << "Case " << testcase << ": " << Answer.second[K] << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 2300
memory_kb: 8732
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#define ll long long
#define rep(i, n) for(ll i = 0; i < (n); i++)
#define rep2(i, a, b) for(ll i = (a); i < (b); i++)
#define vi vector<int>
#define si(c) int(c.size())
using namespace std;

int main() {
    rep2(tnum, 1, 1e9) {
        int n, t, k;
        cin >> n >> t >> k;
        if(!n) exit(0);
        cout << "Case " << tnum << ": ";

        vector<vector<pair<int, int>>> g(n);

        rep(i, n - 1) {
            int x, y, c;
            cin >> x >> y >> c;
            x--, y--;
            g[x].emplace_back(y, c);
            g[y].emplace_back(x, c);
        }

        vector<int> a(n);
        rep(i, t) {
            int x;
            cin >> x;
            a[--x] = true;
        }

        auto dfs = [&](auto &&f, int x, int p) -> array<vi, 2> {
            array<vi, 2> res;
            res[a[x]].emplace_back(0);
            for(auto [to, cost] : g[x]) {
                if(to == p) continue;
                auto r = f(f, to, x);
                array<vi, 2> nxt;
                rep(a, 2) rep(b, 2) {
                    if(b) {
                        while(si(nxt[a]) < si(res[a]) + si(r[b])) nxt[a].emplace_back(1e9);
                        rep(i, si(res[a])) {
                            rep(j, si(r[b])) { nxt[a][i + j + 1] = min(nxt[a][i + j + 1], res[a][i] + r[b][j] + cost); }
                        }
                    }
                    int c = (a | b);
                    while(si(nxt[c]) < si(res[a]) + si(r[b]) - 1) nxt[c].emplace_back(1e9);
                    rep(i, si(res[a])) rep(j, si(r[b])) { nxt[c][i + j] = min(nxt[c][i + j], res[a][i] + r[b][j]); }
                }
                rep(i, 2) swap(nxt[i], res[i]);
            }
            return res;
        };

        auto res = dfs(dfs, 0, -1);
        // cout << res[1].size() << endl;

        cout << res[1][k] << endl;
    }
}
accuracy: 1
time_ms: 3450
memory_kb: 6768
final_rank: 13

code_snippet: /**
 *    author:  otera
**/
#include<bits/stdc++.h>
using namespace std;

// #define int long long

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using int128_t = __int128_t;
#define repa(i, n) for(int i = 0; i < n; ++ i)
#define repb(i, a, b) for(int i = a; i < b; ++ i)
#define repc(i, a, b, c) for(int i = a; i < b; i += c)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define rep(...) overload4(__VA_ARGS__, repc, repb, repa)(__VA_ARGS__)
#define rep1a(i, n) for(int i = 0; i <= n; ++ i)
#define rep1b(i, a, b) for(int i = a; i <= b; ++ i)
#define rep1c(i, a, b, c) for(int i = a; i <= b; i += c)
#define rep1(...) overload4(__VA_ARGS__, rep1c, rep1b, rep1a)(__VA_ARGS__)
#define rev_repa(i, n) for(int i=n-1;i>=0;i--)
#define rev_repb(i, a, b) assert(a > b);for(int i=a;i>b;i--)
#define rev_rep(...) overload3(__VA_ARGS__, rev_repb, rev_repa)(__VA_ARGS__)
#define rev_rep1a(i, n) for(int i=n;i>=1;i--)
#define rev_rep1b(i, a, b) assert(a >= b);for(int i=a;i>=b;i--)
#define rev_rep1(...) overload3(__VA_ARGS__, rev_rep1b, rev_rep1a)(__VA_ARGS__)
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define eb emplace_back
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define rall(c) c.rbegin(), c.rend()
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define si(c) (int)(c).size()
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
#define kth_bit(x, k) ((x>>k)&1)
#define unless(A) if(!(A))
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll intpow(ll a, ll b, ll m) {ll ans = 1; while(b){ if(b & 1) (ans *= a) %= m; (a *= a) %= m; b /= 2; } return ans; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vc<T>>;
template <class T> using vvvc = vector<vvc<T>>;
template <class T> using vvvvc = vector<vvvc<T>>;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template <class T, class U> using umap = unordered_map<T, U>;
template<class T> void scan(T& a){ cin >> a; }
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ cout << ' '; }
template<class T> void print(const T& a){ cout << a; }
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout << ' '; print(*i); } }
int out(){ cout << '\n'; return 0; }
template<class T> int out(const T& t){ print(t); cout << '\n'; return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); cout << ' '; out(tail...); return 0; }
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0,a1,a2,a3,a4,x,...) x
#define debug_1(x1) cout<<#x1<<": "<<x1<<endl
#define debug_2(x1,x2) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<endl
#define debug_3(x1,x2,x3) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<endl
#define debug_4(x1,x2,x3,x4) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<endl
#define debug_5(x1,x2,x3,x4,x5) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<", "#x5<<": "<<x5<<endl
#ifdef DEBUG
#define debug(...) CHOOSE((__VA_ARGS__,debug_5,debug_4,debug_3,debug_2,debug_1,~))(__VA_ARGS__)
#define dump(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...)
#define dump(...)
#endif

struct io_setup {
    io_setup(int precision = 20) {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout << fixed << setprecision(precision);
    }
} io_setup_ {};

const int inf = 1e9 + 7;

void solve() {
    int n, t, k;
    int testcnt = 1;
    while(cin >> n >> t >> k) {
        if(n == 0 && t == 0 && k == 0) break;
        vvc<P> g(n);
        rep(i, n - 1) {
            INT(u, v, c); -- u, -- v;
            g[u].eb(v, c);
            g[v].eb(u, c);
        }
        vc<int> check(n, 0);
        rep(i, t) {
            INT(x); -- x;
            check[x] = 1;
        }
        vc<int> sz(n);
        auto dfs = [&](auto&&dfs, int v, int p) -> array<vector<int>, 2> {
            sz[v] = 1;
            // vector dp(sz[v] + 1, array<int, 2>{inf, inf});
            array dp { vector<int>(min(k + 1, sz[v] + 1), inf), vector<int>(min(k + 1, sz[v] + 1), inf) };
            dp[check[v]][0] = 0;
            for(auto [nv, c]: g[v]) {
                if(nv == p) continue;
                auto dpnv = dfs(dfs, nv, v);
                int nsz = sz[v] + sz[nv] + 1;
                array ndp { vector<int>(min(k + 1, nsz + 1), inf), vector<int>(min(k + 1, nsz + 1), inf) };

                rep(f, 2) {
                    for(int x = sz[v]; x >= 0; -- x) {
                        if(x > k) continue;
                        rep(nf, 2) {
                            for(int y = sz[nv]; y >= 0; -- y) {
                                if(x + y > k) continue;
                                chmin(ndp[f | nf][x + y], dp[f][x] + dpnv[nf][y]);
                                if(nf) chmin(ndp[f][x + y + 1], dp[f][x] + c + dpnv[nf][y]);
                            }
                        }
                    }
                }
                swap(ndp, dp);
                sz[v] = nsz;
            }
            return dp;
        };
        auto dp = dfs(dfs, 0, -1);
        debug(si(dp[0]));
        int ans = dp[1][k];
        cout << "Case " << testcnt << ": " << ans << endl;
        ++ testcnt;
    }
}

signed main() {
    int testcase = 1;
    // in(testcase);
    while(testcase--) solve();
    return 0;
}
accuracy: 1
time_ms: 5630
memory_kb: 7584
final_rank: 17

code_snippet: /**
 *    author:  otera
**/
#include<bits/stdc++.h>
using namespace std;

// #define int long long

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using int128_t = __int128_t;
#define repa(i, n) for(int i = 0; i < n; ++ i)
#define repb(i, a, b) for(int i = a; i < b; ++ i)
#define repc(i, a, b, c) for(int i = a; i < b; i += c)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define rep(...) overload4(__VA_ARGS__, repc, repb, repa)(__VA_ARGS__)
#define rep1a(i, n) for(int i = 0; i <= n; ++ i)
#define rep1b(i, a, b) for(int i = a; i <= b; ++ i)
#define rep1c(i, a, b, c) for(int i = a; i <= b; i += c)
#define rep1(...) overload4(__VA_ARGS__, rep1c, rep1b, rep1a)(__VA_ARGS__)
#define rev_repa(i, n) for(int i=n-1;i>=0;i--)
#define rev_repb(i, a, b) assert(a > b);for(int i=a;i>b;i--)
#define rev_rep(...) overload3(__VA_ARGS__, rev_repb, rev_repa)(__VA_ARGS__)
#define rev_rep1a(i, n) for(int i=n;i>=1;i--)
#define rev_rep1b(i, a, b) assert(a >= b);for(int i=a;i>=b;i--)
#define rev_rep1(...) overload3(__VA_ARGS__, rev_rep1b, rev_rep1a)(__VA_ARGS__)
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define eb emplace_back
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define rall(c) c.rbegin(), c.rend()
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define si(c) (int)(c).size()
inline ll popcnt(ull a) { return __builtin_popcountll(a); }
#define kth_bit(x, k) ((x>>k)&1)
#define unless(A) if(!(A))
ll intpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll intpow(ll a, ll b, ll m) { ll ans = 1; while (b) { if (b & 1) (ans *= a) %= m; (a *= a) %= m; b /= 2; } return ans; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vc<T>>;
template <class T> using vvvc = vector<vvc<T>>;
template <class T> using vvvvc = vector<vvvc<T>>;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template <class T, class U> using umap = unordered_map<T, U>;
template<class T> void scan(T& a) { cin >> a; }
template<class T> void scan(vector<T>& a) { for (auto&& i : a) scan(i); }
void in() {}
template <class Head, class... Tail> void in(Head& head, Tail&... tail) { scan(head); in(tail...); }
void print() { cout << ' '; }
template<class T> void print(const T& a) { cout << a; }
template<class T> void print(const vector<T>& a) { if (a.empty()) return; print(a[0]); for (auto i = a.begin(); ++i != a.end(); ) { cout << ' '; print(*i); } }
int out() { cout << '\n'; return 0; }
template<class T> int out(const T& t) { print(t); cout << '\n'; return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail) { print(head); cout << ' '; out(tail...); return 0; }
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0,a1,a2,a3,a4,x,...) x
#define debug_1(x1) cout<<#x1<<": "<<x1<<endl
#define debug_2(x1,x2) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<endl
#define debug_3(x1,x2,x3) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<endl
#define debug_4(x1,x2,x3,x4) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<endl
#define debug_5(x1,x2,x3,x4,x5) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<", "#x5<<": "<<x5<<endl
#ifdef DEBUG
#define debug(...) CHOOSE((__VA_ARGS__,debug_5,debug_4,debug_3,debug_2,debug_1,~))(__VA_ARGS__)
#define dump(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...)
#define dump(...)
#endif

struct io_setup {
    io_setup(int precision = 20) {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout << fixed << setprecision(precision);
    }
} io_setup_{};

const int inf = 1e9 + 7;

void solve() {
    int n, t, k;
    int testcnt = 1;
    while (cin >> n >> t >> k) {
        if (n == 0 && t == 0 && k == 0) break;
        vvc<P> g(n);
        rep(i, n - 1) {
            INT(u, v, c); --u, --v;
            g[u].eb(v, c);
            g[v].eb(u, c);
        }
        vc<int> check(n, 0);
        rep(i, t) {
            INT(x); --x;
            check[x] = 1;
        }

        auto inf_vec = [](int sz) {
            return vector<int>(sz, inf);
        };

        vc<int> sz(n);
        auto dfs = [&](auto&& dfs, int v, int p) -> array<vector<int>, 2> {
            sz[v] = 1;
            array dp { inf_vec(sz[v]), inf_vec(sz[v]) };
            dp[check[v]][0] = 0;
            for (auto [nv, c] : g[v]) {
                if (nv == p) continue;
                auto dpnv = dfs(dfs, nv, v);
                int nsz = sz[v] + sz[nv];
                array ndp { inf_vec(nsz), inf_vec(nsz) };
                rep(f, 2) {
                    for (int x = 0; x < sz[v]; ++x) {
                        rep(nf, 2) {
                            for (int y = 0; y < sz[nv]; ++y) {
                                chmin(ndp[f | nf][x + y], dp[f][x] + dpnv[nf][y]);
                                if (nf) {
                                    chmin(ndp[f][x + y + 1], dp[f][x] + c + dpnv[nf][y]);
                                }
                            }
                        }
                    }
                }
                swap(ndp, dp);
                sz[v] = nsz;
            }
            return dp;
        };
        auto dp = dfs(dfs, 0, -1);
        debug(si(dp[0]));
        int ans = dp[1][k];
        cout << "Case " << testcnt << ": " << ans << endl;
        ++testcnt;
    }
}

signed main() {
    int testcase = 1;
    // in(testcase);
    while (testcase--) solve();
    return 0;
}
accuracy: 1
time_ms: 8250
memory_kb: 7564
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define inf 1000000007
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define fi first
#define se second
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define rrep(i,n) for(int i = (int)n-1; i >= 0; --i)
#define srep(i,a,b) for(int i = (int)a; i < (int)(b); ++i)
#define all(x) (x).begin(),(x).end()
#define SUM(v) accumulate(all(v), 0LL)
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())
#define SZ(c) (int)(c).size()
template<typename T>
ostream& operator << (ostream& os, vector<T>& vec) {
    os << "{";
    for (int i = 0; i<(int)vec.size(); i++) {
        os << vec[i] << (i + 1 == (int)vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
// pair出力
template<typename T, typename U>
ostream& operator << (ostream& os, pair<T, U> pair_var) {
    os << "(" << pair_var.first << ", " << pair_var.second << ")";
    return os;
}
// map出力
template<typename T, typename U>
ostream& operator << (ostream& os, map<T, U>& map_var) {
    os << "{";
    for(auto itr = map_var.begin(); itr != map_var.end(); itr++){
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if(itr != map_var.end()) os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
// set 出力
template<typename T>
ostream& operator << (ostream& os, set<T>& set_var) {
    os << "{";
    for(auto itr = set_var.begin(); itr != set_var.end(); itr++){
        os << (*itr);
        ++itr;
        if(itr != set_var.end()) os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
// tuple 出力
template<int N,class Tuple>
void out(ostream &os,const Tuple &t){}
template<int N,class Tuple,class H,class ...Ts>
void out(ostream &os,const Tuple &t){
    if(N)os<<", ";
    os<<get<N>(t);
    out<N+1,Tuple,Ts...>(os,t);
}
template<class ...Ts>
ostream& operator<<(ostream &os, const tuple<Ts...> &t){
    os<<"(";
    out<0,tuple<Ts...>,Ts...>(os,t);
    os<<")";
    return os;
}
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                                                                  \
    vector<type> name(size);                                                                                                                                   \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                                                                   \
    vector<vector<type>> name(h, vector<type>(w));                                                                                                             \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)                                                                                                                         \
    vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define INT(...)                                                                                                                                               \
    int __VA_ARGS__;                                                                                                                                           \
    IN(__VA_ARGS__)
#define LL(...)                                                                                                                                                \
    ll __VA_ARGS__;                                                                                                                                            \
    IN(__VA_ARGS__)
#define STR(...)                                                                                                                                               \
    string __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                                                                               \
    char __VA_ARGS__;                                                                                                                                          \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                                                                               \
    double __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
template <class T> void scan(vector<T> &);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
    scan(head);
    IN(tail...);
}
const string YESNO[2] = {"NO", "YES"};
const string YesNo[2] = {"No", "Yes"};
const string yesno[2] = {"no", "yes"};
void YES(bool t = 1) { cout << YESNO[t] << endl; }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { cout << YesNo[t] << endl; }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { cout << yesno[t] << endl; }
void no(bool t = 1) { yes(!t); }
#ifdef LOCAL
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << H;
    debug_out(T...);
}
#define dbg(...) \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define dbg(...) (void(0))
#define dump(x) (void(0))
#endif
template<typename A, typename T>
std::enable_if_t<std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    array = val;
}
template<typename A, typename T>
std::enable_if_t<!std::is_convertible<T, A>::value> fill(A& array, const T& val)
{
    for (auto& a : array) {
        fill(a, val);
    }
}
template <typename T, typename S> T ceil(T x, S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}
template <typename T, typename S> T floor(T x, S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
vector<int> iota(int n) {vector<int> a(n);iota(all(a), 0);return a;}
template <class T> T POW(T x, int n) {T res = 1;for(; n; n >>= 1, x *= x){if(n & 1) res *= x;}return res;}
ll pow2(int i) { return 1LL << i; }
int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(ll t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int lowbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int lowbit(ll a) { return a == 0 ? 64 : __builtin_ctzll(a); }
// int allbit(int n) { return (1 << n) - 1; }
ll allbit(ll n) { return (1LL << n) - 1; }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(ll t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }


template <class S> void fold_in(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void fold_in(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto e : a) v.emplace_back(e);
    fold_in(v, tail...);
}
template <class S> void renumber(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void renumber(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto &&e : a) e = lb(v, e);
    renumber(v, tail...);
}
template <class S, class... Args> void zip(vector<S> &head, Args &&...args) {
    vector<S> v;
    fold_in(v, head, args...);
    sort(all(v)), v.erase(unique(all(v)), v.end());
    renumber(v, head, args...);
}
template<class T> inline bool chmax(T &a, T b){
    if(a<b){
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
class UnionFind {
private:
    int sz;
    vector<int> par, size_,spe;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), size_(sz, 1),spe(sz){
        iota(par.begin(), par.end(), 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(size_[x] < size_[y]) swap(x,y);
        par[y] = x;
        size_[x] += size_[y];
        spe[x] += spe[y];
    }
    int size(int x){
        x = find(x);
        return size_[x];
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
    void set_spe(int x){
        spe[x] = 1;
    }
    int special(int x){
        x = find(x);
        return spe[x];
    }
};

int main(){
    int counter = 0;
    while(1){
        counter++;
        INT(n,t,k);
        if(n==0)break;
        priority_queue<tuple<int,int,int> > pq;
        int res = 0;
        rep(i,n-1){
            INT(u,v,s);
            u--;v--;
            pq.push(MT(s,u,v));
            res += s;
        }
        UnionFind uf(n);
        rep(i,t){
            INT(a);
            a--;
            uf.set_spe(a);
        }
        int C = 0;
        while(!pq.empty()){
            auto [s,u,v] = pq.top();
            pq.pop();
            if(uf.special(u)&&uf.special(v)){
                if(C==t-k-1){
                    continue;
                }else{
                    C++;
                }
            }
            uf.unite(u,v);
            res -= s;
        }
        cout << "Case " << counter << ": " <<  res << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3264
final_rank: 7

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

struct UnionFind{
	vl p;
	vl rank;
	vl cnt;

	UnionFind(ll n){
		rank.resize(n,0);
		p.resize(n,0);
		cnt.resize(n,0);
		rep(i,n){
			p[i] = i;
			rank[i] = 0;
			cnt[i] = 1;
		}
	}

	ll find(ll x){
		if(x != p[x]) p[x] = find(p[x]);
		return p[x];
	}

	bool same(ll x, ll y){
		return find(x) == find(y);
	}

	void unite(ll x, ll y){
		x = find(x);
		y = find(y);
		if(x == y) return;
		if(rank[x] > rank[y]){
			p[y] = x;
			cnt[x] += cnt[y];
		}else{
			p[x] = y;
			cnt[y] += cnt[x];
			if(rank[x] == rank[y]) rank[y]++;
		}
	}

	ll size(ll x){
		return cnt[find(x)];
	}
};

int main(){
	int T = 1;
	while(1){
		int n,t,k; cin >> n >> t >> k;
		if(!n) break; 
		vector<tapu> edge(n-1);
		rep(i,n-1){
			int u,v,c; cin >> u >> v >> c; u--; v--;
			edge[i] = tie(c,u,v);
		}
		sort(rall(edge));
		vb a(n,false);
		UnionFind uf(n);
		int rest = t - (k+1);
		int e = n-k;
		rep(i,t){
			int p; cin >> p; p--;
			a[p] = true;
		}
		int ans = 0;
		rep(i,n-1){
			int c,u,v;
			tie(c,u,v) = edge[i];
			ans += c;
			if(e == 0) continue;
			int U = uf.find(u);
			int V = uf.find(v);
			if(a[U] && a[V]){
				if(rest == 0) continue;
				rest--;
			}
			ans -= c;
			uf.unite(u,v);
			int nxt = uf.find(u);
			a[nxt] = a[U] || a[V];
			e--;
		}
		cout << "Case " << T << ": " << ans << "\n";
		T++;
	}
}
accuracy: 1
time_ms: 110
memory_kb: 3632
final_rank: 9

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

int main(){
	int T = 1;
	while(1){
		int n,t,k; cin >> n >> t >> k;
		if(!n) break; 
		vector<vpl> G(n);
		rep(i,n-1){
			int u,v,c; cin >> u >> v >> c; u--; v--;
			G[u].emplace_back(v,c);
			G[v].emplace_back(u,c);
		}
		vb a(n,false);
		rep(i,t){
			int p; cin >> p; p--;
			a[p] = true;
		}
		vector<pii> ep(n+1,{inf,inf});
		vector<int> c(n,1);
 		auto dfs = [&](auto &&dfs, int u, int p) -> vector<pii> {
			vector<pii> dp(1,{inf,inf});
			dp[0].first = 0;
			for(auto v : G[u]){
				if(v.first == p) continue;
				vector<pii> res = dfs(dfs,v.first,u);
				rep(i,c[u]+c[v.first]) rep(j,2) ep[i] = {inf,inf};
				rep(i,c[u]) rep(j,c[v.first]){
					chmin(ep[i+j].first, dp[i].first + res[j].first);
					chmin(ep[i+j].second, dp[i].first + res[j].second);
					chmin(ep[i+j].second, dp[i].second + res[j].first);
					chmin(ep[i+j].second, dp[i].second + res[j].second);
					chmin(ep[i+j+1].first, dp[i].first + res[j].second + v.second);
					chmin(ep[i+j+1].second, dp[i].second + res[j].second + v.second);
				}
				c[u] += c[v.first];
				dp.resize(c[u]);
				rep(i,c[u]) dp[i] = ep[i];
				res.clear();
			}
			if(a[u]){
				rep(i,c[u]){
					chmin(dp[i].second, dp[i].first);
					dp[i].first = inf;
				}
			}
			return dp;
		};
		auto res = dfs(dfs,0,-1);
		cout << "Case " << T << ": " << res[k].second << "\n";
		T++;
	}
}
accuracy: 1
time_ms: 4830
memory_kb: 6068
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;

struct UnionFind {
	vector<int> p,e;
	UnionFind(int n) { p.resize(n, -1); e.resize(n, 0); }

	int unite(int a, int b) {
		int x = root(a), y = root(b); e[x]++;
		if(x == y) return x;
		if(-p[x] < -p[y]) swap(x, y);
		p[x] += p[y];
		p[y] = x;
		e[x] += e[y];
		return x;
	}

	bool same(int a, int b) { return root(a) == root(b); }

	int root(int a) {
		if(p[a] < 0) return a;
		return p[a] = root(p[a]);
	}

	int size(int a) { return -p[root(a)]; }
	int edge_size(int a) { return e[root(a)]; }
};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(0);

	int cases = 1;
	while(true) {
		int n,t,k; cin >> n >> t >> k; if(n == 0) break;
		vector<pair<int,pair<int,int>>> edges;
		int ans = 0;
		rep(_,n-1) {
			int u,v,c; cin >> u >> v >> c;
			u--; v--;
			edges.push_back({c, {u, v}});
			ans += c;
		}
		sort(edges.rbegin(), edges.rend());

		vector<bool> is_base(n, false);
		rep(_,t) {
			int b; cin >> b; b--;
			is_base[b] = true;
		}

		UnionFind uf(n);
		int cnt = t - k - 1;
		for(auto e : edges) {
			int u = e.second.first, v = e.second.second, c = e.first;
			u = uf.root(u); v = uf.root(v);
			if(is_base[u] && is_base[v]) {
				if(cnt > 0) {
					cnt--;
					ans -= c;
					uf.unite(u, v);
				}
			} else {
				uf.unite(u, v);
				ans -= c;
				is_base[u] = is_base[v] = (is_base[u] | is_base[v]);
			}
		}

		printf("Case %d: %d\n", cases++, ans);
	}
}
accuracy: 1
time_ms: 40
memory_kb: 3492
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=15,INF=1<<29;

//Union Find

struct UF{
    int n;
    vector<int> par,size,aru;
    
    void init(int n_){
        n=n_;
        par.assign(n,-1);
        size.assign(n,1);
        aru.assign(n,0);
        
        for(int i=0;i<n;i++){
            par[i]=i;
        }
    }
    
    int root(int a){
        if(par[a]==a) return a;
        else return par[a]=root(par[a]);
    }
    
    void unite(int a,int b){
        if(root(a)!=root(b)){
            size[root(a)]+=size[root(b)];
            aru[root(a)]|=aru[root(b)];
            par[root(b)]=root(a);
        }
    }
    
    bool check(int a,int b){
        return root(a)==root(b);
    }
};

void output(int i){
    cout<<"Case "<<i<<": ";
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    int q=1;
    while(1){
        int N,T,K;cin>>N>>T>>K;
        if(N==0) break;
        output(q);q++;
        
        vector<pair<pair<int,int>,int>> E(N-1);
        for(int i=0;i<N-1;i++){
            int a,b,c;cin>>a>>b>>c;
            a--;b--;
            E[i]=mp(mp(a,b),c);
        }
        
        UF uf;uf.init(N);
        for(int i=0;i<T;i++){
            int x;cin>>x;
            x--;
            uf.aru[x]=true;
        }
        
        int ok=T-(K+1);
        
        sort(all(E),[](auto a,auto b){
            return a.se>b.se;
        });
        
        int ans=0;
        
        for(auto e:E){
            int a=uf.root(e.fi.fi),b=uf.root(e.fi.se),c=e.se;
            if(uf.aru[a]&&uf.aru[b]){
                if(ok){
                    uf.unite(a,b);
                    ok--;
                }else{
                    ans+=c;
                }
            }else{
                uf.unite(a,b);
            }
        }
        
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3468
final_rank: 2

code_snippet: /*	author:  Kite_kuma
	created: 2021.09.30 19:12:42 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

#pragma region union_find

struct UF {
   private:
	std::vector<int> data;	// data[root] = -size, data[not_root] = parent

   public:
	int components;	 // number of components

	UF(int N) : data(N, -1), components(N) {}

	int root(int x) {
		if(data[x] < 0) return x;
		return data[x] = root(data[x]);
	}

	bool same(int x, int y) { return root(x) == root(y); }

	bool unite(int x, int y) {	// merge x and y
		x = root(x);
		y = root(y);
		if(x == y) return false;
		components--;
		if(data[x] > data[y]) std::swap(x, y);	// balancing
		data[x] += data[y];
		data[y] = x;
		return true;
	}

	int size(int x) { return -data[root(x)]; }

	std::vector<std::vector<int>> groups() {
		std::vector<std::vector<int>> g(data.size()), ret;
		for(size_t i = 0; i < data.size(); i++) g[root(i)].push_back((int)i);
		for(auto &vec : g)
			if(!vec.empty()) ret.push_back(vec);
		return ret;
	}
};

#pragma endregion

ll solve(int n) {
	debug(n);
	int t, k;
	cin >> t >> k;
	// Graph g(n);

	ll ans = 0;
	V<tuple<ll, int, int>> edges;
	rep(n - 1) {
		int a, b;
		ll c;
		cin >> a >> b >> c;
		edges.emplace_back(c, a - 1, b - 1);
		ans += c;
	}

	UF uf(n);

	vi has_base(n);

	int pre;
	cin >> pre;
	pre--;
	has_base[pre] = 1;
	rep(t - 1) {
		int now;
		cin >> now;
		now--;
		uf.unite(now, pre);
		swap(pre, now);
		has_base[pre] = 1;
	}

	debug(edges.size());

	sort(all(edges));

	// int use_edges_count = n - 1 - k;
	int base_conn_limit = t - k - 1;
	while(!edges.empty()) {
		int a, b;
		ll c;
		tie(c, a, b) = edges.back();
		edges.pop_back();
		a = uf.root(a);
		b = uf.root(b);
		if(has_base[a] && has_base[b]) {
			if(base_conn_limit) {
				base_conn_limit--;
			} else {
				continue;
			}
		} else if(has_base[a] || has_base[b]) {
			has_base[a] = has_base[b] = 1;
		}
		uf.unite(a, b);
		ans -= c;
	}

	return ans;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	int t;
	int cs = 0;
	while(cin >> t && t) {
		cs++;
		cout << "Case " << cs << ": " << solve(t) << dl;
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3516
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
int main(){
  int T = 0;
  while (true){
    int n, t, k;
    cin >> n >> t >> k;
    if (n == 0 && t == 0 && k == 0){
      break;
    }
    vector<vector<pair<int, int>>> E(n);
    for (int i = 0; i < n - 1; i++){
      int v, w, c;
      cin >> v >> w >> c;
      v--;
      w--;
      E[v].push_back(make_pair(c, w));
      E[w].push_back(make_pair(c, v));
    }
    vector<bool> base(n, false);
    for (int i = 0; i < t; i++){
      int v;
      cin >> v;
      v--;
      base[v] = true;
    }
    vector<int> p(n, -1);
    vector<vector<pair<int, int>>> c(n);
    queue<int> Q;
    Q.push(0);
    vector<int> bfs;
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      bfs.push_back(v);
      for (auto P : E[v]){
        int w = P.second;
        if (w != p[v]){
          p[w] = v;
          c[v].push_back(P);
          Q.push(w);
        }
      }
    }
    reverse(bfs.begin(), bfs.end());
    vector<vector<vector<int>>> dp(2, vector<vector<int>>(n));
    for (int v : bfs){
      dp[0][v] = vector<int>(1, 0);
      dp[1][v] = vector<int>(1, INF);
      for (auto P : c[v]){
        int d = P.first;
        int w = P.second;
        int cnt1 = dp[0][v].size();
        int cnt2 = dp[0][w].size();
        vector<vector<int>> dp2(2, vector<int>(cnt1 + cnt2, INF));
        for (int i = 0; i < cnt1; i++){
          for (int j = 0; j < cnt2; j++){
            dp2[0][i + j] = min(dp2[0][i + j], dp[0][v][i] + dp[0][w][j]);
            dp2[1][i + j] = min(dp2[1][i + j], dp[0][v][i] + dp[1][w][j]);
            dp2[1][i + j] = min(dp2[1][i + j], dp[1][v][i] + dp[0][w][j]);
            dp2[0][i + j + 1] = min(dp2[0][i + j + 1], dp[0][v][i] + dp[1][w][j] + d);
            dp2[1][i + j + 1] = min(dp2[1][i + j + 1], dp[1][v][i] + dp[1][w][j] + d);
          }
        }
        swap(dp[0][v], dp2[0]);
        swap(dp[1][v], dp2[1]);
        for (int i = 0; i < 2; i++){
          dp[i][w].clear();
          dp[i][w].shrink_to_fit();
        }
      }
      if (base[v]){
        int cnt = dp[0][v].size();
        for (int i = 0; i < cnt; i++){
          dp[1][v][i] = min(dp[1][v][i], dp[0][v][i]);
        }
      }
    }
    cout << "Case " << T + 1 << ": " << dp[1][0][k] << endl;
    T++;
  }
}
accuracy: 1
time_ms: 4140
memory_kb: 5476
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
vector<vector<int>> dfs(vector<vector<pair<int, int>>> &c, vector<bool> &base, int k, int v = 0){
  vector<vector<int>> dp(2);
  dp[0] = {0};
  dp[1] = {INF};
  for (auto P : c[v]){
    int d = P.first;
    int w = P.second;
    vector<vector<int>> dp2 = dfs(c, base, k, w);
    int cnt1 = dp[0].size();
    int cnt2 = dp2[0].size();
    vector<vector<int>> dp3(2, vector<int>(cnt1 + cnt2, INF));
    for (int i = 0; i < cnt1; i++){
      for (int j = 0; j < cnt2; j++){
        dp3[0][i + j] = min(dp3[0][i + j], dp[0][i] + dp2[0][j]);
        dp3[1][i + j] = min(dp3[1][i + j], dp[0][i] + dp2[1][j]);
        dp3[1][i + j] = min(dp3[1][i + j], dp[1][i] + dp2[0][j]);
        dp3[0][i + j + 1] = min(dp3[0][i + j + 1], dp[0][i] + dp2[1][j] + d);
        dp3[1][i + j + 1] = min(dp3[1][i + j + 1], dp[1][i] + dp2[1][j] + d);
      }
    }
    swap(dp, dp3);
  }
  int cnt = dp[0].size();
  if (base[v]){
    for (int i = 0; i < cnt; i++){
      dp[1][i] = min(dp[1][i], dp[0][i]);
    }
  }
  while (cnt > k + 1){
    dp[0].pop_back();
    dp[1].pop_back();
    cnt--;
  }
  return dp;
}
int main(){
  int T = 0;
  while (true){
    int n, t, k;
    cin >> n >> t >> k;
    if (n == 0 && t == 0 && k == 0){
      break;
    }
    vector<vector<pair<int, int>>> E(n);
    for (int i = 0; i < n - 1; i++){
      int v, w, c;
      cin >> v >> w >> c;
      v--;
      w--;
      E[v].push_back(make_pair(c, w));
      E[w].push_back(make_pair(c, v));
    }
    vector<bool> base(n, false);
    for (int i = 0; i < t; i++){
      int v;
      cin >> v;
      v--;
      base[v] = true;
    }
    vector<int> p(n, -1);
    vector<vector<pair<int, int>>> c(n);
    queue<int> Q;
    Q.push(0);
    vector<int> bfs;
    while (!Q.empty()){
      int v = Q.front();
      Q.pop();
      bfs.push_back(v);
      for (auto P : E[v]){
        int w = P.second;
        if (w != p[v]){
          p[w] = v;
          c[v].push_back(P);
          Q.push(w);
        }
      }
    }
    reverse(bfs.begin(), bfs.end());
    vector<int> sz(n, 1);
    for (int v : bfs){
      for (auto P : c[v]){
        int w = P.second;
        sz[v] += sz[w];
      }
    }
    for (int i = 0; i < n; i++){
      int cnt = c[i].size();
      vector<tuple<int, int, int>> c2(cnt);
      for (int j = 0; j < cnt; j++){
        int w = c[i][j].second;
        c2[j] = make_tuple(sz[w], c[i][j].first, w);
      }
      sort(c2.begin(), c2.end());
      for (int j = 0; j < cnt; j++){
        c[i][j].first = get<1>(c2[j]);
        c[i][j].second = get<2>(c2[j]);
      }
    }
    vector<vector<int>> dp = dfs(c, base, k);
    cout << "Case " << T + 1 << ": " << dp[1][k] << endl;
    T++;
  }
}
accuracy: 1
time_ms: 3860
memory_kb: 7804
final_rank: 15

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}

struct UnionFind{
    vector<int> par,num;
    UnionFind(int n):par(n),num(n,1){
        iota(par.begin(),par.end(),0);  //include<numeric>
    }
    int find(int v){
        return (par[v]==v)?v:(par[v]=find(par[v]));
    }
    void unite(int u,int v){
        u=find(u),v=find(v);
        if(u==v)return;
        if(num[u]<num[v])swap(u,v);
        num[u]+=num[v];
        par[v]=u;
    }
    bool same(int u,int v){
        return find(u) == find(v);
    }
    int size(int v){
        return num[find(v)];
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int Case = 0;
    int n,t,k;
    while(cin >> n >> t >> k,n){
        Case++;
        int res = 0;
        vector<pair<int,pair<int,int>>> eg;
        for(int i=0;i<n-1;i++){
            int x,y; cin >> x >> y;
            x--; y--;
            int cost; cin >> cost;
            eg.push_back({cost,{x,y}});
        }
        sort(eg.rbegin(), eg.rend());
        vector<int> base(n);
        for(int i=0;i<t;i++){
            int x; cin >> x;
            base[x-1] = 1;
        }
        int cnt = t;
        UnionFind uf(n);
        for(int i=0;i<eg.size();i++){
            int x = uf.find(eg[i].second.first);
            int y = uf.find(eg[i].second.second);
            int cost = eg[i].first;
            if(base[x] and base[y] and cnt == k+1){
                res += cost;
                continue;
            }
            uf.unite(x,y);
            if(base[x] and base[y]){
                cnt--;
            }
            base[x] = base[y] = (base[x] | base[y]);
        }
        printf("Case %d: %d\n",Case,res);
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3352
final_rank: 1