Waver's Flight
Difficulty: Hard

Waver needs to get out of the Clock Tower immediately. The Clock Tower is a tree of $N$ vertices numbered $1$ through $N$. Additionally, there are $E$ shortcut edges. Using shortcuts arouses suspicion, therefore Waver has decided that he will use shortcuts at most $K$ times. He needs to get to an exit to leave the place. All leaf vertices are exit nodes. Each edge, normal and shortcut, is weighted, which indicates the time taken to traverse it. 

Waver wants to exit the Clock Tower as soon as possible. Print the least units of time Waver needs to reach an exit node from every vertex.

Input Format:
The first line contains three integers: $N$ (the number of vertices), $E$ (the number of shortcut edges), and $K$ (the number of times shortcut edges can be used).
 
The next $N-1$ lines contain three integers, $a$, $b$, and $w$ each, indicating that vertices $a$ and $b$ are connected by a tree edge of weight $w$.
 
$E$ lines follow, each having three integers, $a$, $b$, and $w$, such that $a$ and $b$ are connected by a shortcut edge of weight $w$.

**Constraints**  
$1 \le N \le 10000$  
$0 \le E \le 20000$  
$0 \le K \le 1000$

For all edges: $1 \le w \le 1000$  
There is at most one shortcut edge between any pair of vertices.  
There is no shortcut from a vertex to itself.  
All edges are bidirectional.  
Note that two vertices can be connected both by a tree edge and a shortcut edge.

Output Format:
Output must consist of $N$ lines, where the $i$<sup>$th$</sup> line has a single integer denoting the least units of time Waver needs to the exit from vertex $i$.

Sample Input:
    6 2 1
    1 5 25
    5 4 1
    6 4 11
    4 3 10
    2 3 100
    3 4 7
    5 1 3

Sample Output:
    0
    0
    14
    4
    3
    0

Python 3 starter code:


Reference solution (C++):
    /*
     * Bidhan Roy
     * University of Dhaka
     */

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

    #define rep(i,n) for(auto i=0; i<(n); i++)
    #define mem(x,val) memset((x),(val),sizeof(x));
    #define rite(x) freopen(x,"w",stdout);
    #define read(x) freopen(x,"r",stdin);
    #define all(x) x.begin(),x.end()
    #define sz(x) ((int)x.size())
    #define sqr(x) ((x)*(x))
    #define pb push_back
    #define clr clear()
    #define inf (1<<30)
    #define ins insert
    #define xx first
    #define yy second
    #define eps 1e-9

    typedef long long i64;
    typedef unsigned long long ui64;
    typedef string st;
    typedef vector<int> vi;
    typedef vector<st> vs;
    typedef map<int,int> mii;
    typedef map<st,int> msi;
    typedef set<int> si;
    typedef set<st> ss;
    typedef pair<int,int> pii;
    typedef vector<pii> vpii;

    int getInteger( int lo, int hi, st var = "" ) {
        int ret;
        cin >> ret;
        if( lo <= ret && ret <= hi ) return ret;
        cout << var << " should be between [" << lo <<"," << hi << "]" << endl;
        throw;
    }

    #define mx 10010

    vpii edge[mx];
    vector< tuple< int, int, int > > extra;

    int dp[mx];

    void dfs( int u, int par = -1 ) {
        //if( par != -1 ) cout << par << " " << u << endl;
        bool ent = false;

        for( auto &x: edge[u] ) {

            int v = x.xx;
            int w = x.yy;

            if( v == par ) continue;

            ent = true;

            dfs( v, u );
            dp[u] = min( dp[u], dp[v] + w );

        }
        //cout << u << " = " << ent << endl;
        if( !ent || ( par == -1 && sz(edge[u]) == 1 ) ) dp[u] = 0;
    }

    void dfs2( int u, int par = -1 ) {
        bool ent = false;

        for(auto &x: edge[u]) {

            int v = x.xx;
            int w = x.yy;

            if(v == par) continue;

            ent = true;

            dp[v] = min( dp[v], dp[u] + w );
            dfs2( v, u );
        }

        if( !ent ) dp[u] = 0;
    }

    int temp[mx], n;

    void relax( ) {
        fill( temp, temp+n, 1<<29 );
        rep(i,n) temp[i] = dp[i];
        for( auto &x : extra ) {
            int u = get<0>(x);
            int v = get<1>(x);
            int w = get<2>(x);
            temp[u] = min( temp[u], dp[v] + w );
            temp[v] = min( temp[v], dp[u] + w );
        }
        rep(i,n) dp[i] = temp[i];
    }

    int main() {
        //read("in.txt");
        ios_base::sync_with_stdio(0);
        int e, k;
        n = getInteger(1,10000,"n");
        e = getInteger(0,20000,"e");
        k = getInteger(0,1000,"k");

        rep( i, n-1 ) {
            int u, v, w;
            u = getInteger(1,n,"u");
            v = getInteger(1,n,"v");
            w = getInteger(1,1000,"w");
            u--, v--;
            edge[u].pb( {v,w} );
            edge[v].pb( {u,w} );
        }

        while( e-- ){
            int u, v, w;
            u = getInteger(1,n,"u");
            v = getInteger(1,n,"v");
            w = getInteger(1,1000,"w");
            u--, v--;
            extra.pb( tuple<int,int,int>( u, v, w) );
        }

        fill( dp, dp+n, 1<<29 );

        dfs(0); dfs2(0);

        while( k-- ) {
            relax();
            dfs(0);
            dfs2(0);
        }

        rep(i,n) cout << dp[i] << endl;

        return 0;
    }