Problem:
G: 旅費支給 - Travel Support -
物語
私，香坂穂乃果16歳！学生アイドルをやっています！！
学生アイドルの良さをみんなに伝えるためのライブをやろうと，たくさんの学生アイドルの人たちを呼んでアキバスタジアムでライブをします．
だけど，遠くから来るライブ参加者もいてとっても電車賃がかかるの．だからu’sのメンバーでバイトをして，ライブ参加者たちに電車賃を渡すことにしたんだ！ただ，バイト代が入るのが遅いから電車賃を渡すのがライブ参加者の出発に間に合わないことがあったり，バイト代が足りなくて電車賃の全額は渡せないことがあるんだ．そんな時は，ライブ参加者に足りない分のお金を事前に用意してもらうのだけど，どのくらい用意して貰えばいいんだろう？
そこで，あなたにライブ参加者が用意する必要のある最小の金額を求めて欲しいんだ！
おねがい真衣ちゃん，電車賃貸して？
問題
N
個の都市があり，それぞれ
1
〜
N
までの番号がつけられている．
i
（
1 ≤ i ≤ N
）番目の都市は人口が
t_i
（
i ≠ j
ならば
t_i ≠ t_j
）である．
現在，都市1に
K
人のライブ参加者が集まろうとしている．許された交通手段が
M
通りあり，
i
番目の交通手段では都市
a_i
と都市
b_i
（
1 ≤ a_i, b_i ≤ N
）を
c_i
円の費用で双方向に移動ができる．移動にはどの交通手段でも1日を必要とする．
i
（
1 ≤ i ≤ K
）番目の参加者は，都市
x_i
を出発し必要な費用が最小になるような経路で都市1に向かう．費用が最小な経路が複数ある場合は，移動日数が少ない経路を選ぶ．それでも複数の経路がある場合は，人口が少ない都市へ優先して移動するような経路を選ぶ．これにより経路が定まり到着するまでの日数がわかるので，参加者はそれぞれライブが行われる日にちょうど都市1に到着するように移動を開始する．
また，
i
（
1 ≤ i ≤ K
）番目の参加者にはライブの
d_i
日前に
p_i
円の支給がある事が知らされている．支給後の移動には可能なかぎり支給された費用を用いるが，支給前にかかっている費用や，賄いきれない支給後の費用は，各参加者が事前に用意する必要がある．
それぞれの参加者が事前に用意する費用の最小値を求めよ．
入力形式
入力は次の形式で与えられる．
N
M
t_1
...
t_N
a_1
b_1
c_1
...
a_M
b_M
c_M
K
x_1
d_1
p_1
...
x_K
d_K
p_K
1行目には2つの整数
N
（
1 ≤ N ≤ 100,000
），
M
（
0 ≤ M ≤ 500,000
）が空白区切りで与えられ，それぞれ都市数と許された交通手段の数を表す．2行目には
N
個の整数
t_i
（
1 ≤ i ≤ N
，
1 ≤ t_i ≤ 500,000
）が空白区切りで与えられる．
t_i
は都市
i
の人口を表し，
i ≠ j
ならば
t_i ≠ t_j
を満たす．
続く
M
行は交通手段についての入力であり，
i
番目の交通手段について3つの整数
a_i
，
b_i
，
c_i
が空白区切りで与えられる．これは，
i
番目の交通手段で都市
a_i
と
b_i
（
1 ≤ a_i, b_i ≤ N
,
a_i ≠ b_i
）を行き来でき，
c_i
（
1 ≤ c_i ≤ 10,000
）円の費用がかかることを表す．また，任意の2つの都市を直接結ぶ2つ以上の交通手段は無い．全ての都市は，いくつかの交通手段を用いて互いに行き来できる．
次の行には参加者の人数を表す整数
K
（
1 ≤ K ≤ 100,000
）が与えられる．
続く
K
行は参加者たちについての入力であり，
i
番目の参加者について3つの整数
x_i, d_i, p_i
が空白区切りで与えられる．これは，
i
番目の参加者が最初は都市
x_i
（
1 ≤ x_i ≤ N
）におり，ライブの
d_i
（
0 ≤ d_i ≤ 100,000
）日前に
p_i
（
0 ≤ p_i ≤ 100,000
）円の支給を受けることを表す．
出力形式
それぞれの参加者が事前に用意する費用の最小値を，1番目の参加者から順に改行区切りで出力せよ．
入出力が非常に大きくなる可能性があるので，入出力の関数には高速なものを用いることを推奨する．
入力例1
5 6
100 80 70 60 50
1 2 500
2 5 100
1 3 400
1 4 200
3 5 700
4 5 800
1
5 3 600
出力例1
0
移動全体にかかる費用の最小値は600円で，2日間で都市1につくことができる．3日前に十分な費用が支給されるので，事前に費用を用意する必要はない．
入力例2
5 6
400 200 500 300 100
1 2 500
2 5 100
1 3 400
1 4 200
3 5 200
4 5 800
1
5 1 800
出力例2
100
費用が最小でありかつ日数が最小となる経路は
5−2−1
と
5−3−1
の2つの経路があるが，都市5から次の都市へ移動する際に，都市3より都市2の方が人口が少ないので経路
5−2−1
を選ぶ．合計の費用は600円なの支給額で全額支払い可能であるが，支給されるより前の費用は立て替えなければならないので，
5−2
間の費用である100円だけ事前に用意する必要がある．
入力例3
10 13
100 90 80 70 60 50 40 30 20 10
1 2 5
1 4 4
2 3 3
3 5 2
4 5 6
4 6 7
4 7 2
5 8 1
5 9 8
6 7 10
6 9 7
6 10 3
7 10 10
10
2 0 0
2 1 3
3 0 100000
3 1 3
3 1 100000
3 2 100000
3 100000 100000
8 1 5
9 2 11
10 0 0
出力例3
5
2
8
5
3
0
0
7
7
14

Submitted solutions:

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <climits>

using namespace std;

const int MAX_N = 100000;
const int MAX_D = 20;
typedef long long ll;
const ll INF = 1LL << 60;

struct Edge {
    int to;
    int cost;
    Edge(int t, int c) : to(t), cost(c) {}
};

struct State {
    ll total_cost;
    int depth;
    int node;
    State(ll c, int d, int n) : total_cost(c), depth(d), node(n) {}
    
    bool operator<(const State& other) const {
        if (total_cost != other.total_cost) {
            return total_cost > other.total_cost;
        }
        return depth > other.depth;
    }
};

vector<int> tree_types;
vector<vector<Edge>> graph;
vector<ll> min_costs;
vector<int> depths;
vector<vector<int>> ancestors;

void dijkstra(int start, int n) {
    min_costs.assign(n, INF);
    depths.assign(n, 0);
    ancestors.assign(n, vector<int>(MAX_D, -1));
    
    min_costs[start] = 0;
    priority_queue<State> pq;
    pq.push(State(0, 0, start));
    
    while (!pq.empty()) {
        State current = pq.top();
        pq.pop();
        
        if (current.total_cost != min_costs[current.node] || 
            current.depth != depths[current.node]) {
            continue;
        }
        
        for (const Edge& edge : graph[current.node]) {
            int neighbor = edge.to;
            ll new_cost = current.total_cost + edge.cost;
            int new_depth = current.depth + 1;
            
            if (new_cost < min_costs[neighbor]) {
                min_costs[neighbor] = new_cost;
                depths[neighbor] = new_depth;
                ancestors[neighbor][0] = current.node;
                pq.push(State(new_cost, new_depth, neighbor));
            }
            else if (new_cost == min_costs[neighbor]) {
                if (new_depth < depths[neighbor]) {
                    depths[neighbor] = new_depth;
                    ancestors[neighbor][0] = current.node;
                    pq.push(State(new_cost, new_depth, neighbor));
                }
                else if (new_depth == depths[neighbor] && 
                         tree_types[ancestors[neighbor][0]] > tree_types[current.node]) {
                    ancestors[neighbor][0] = current.node;
                }
            }
        }
    }
    
    // Build binary lifting table
    for (int d = 1; d < MAX_D; ++d) {
        for (int i = 0; i < n; ++i) {
            if (ancestors[i][d-1] != -1) {
                ancestors[i][d] = ancestors[ancestors[i][d-1]][d-1];
            }
        }
    }
}

int find_ancestor(int node, int steps) {
    for (int d = MAX_D - 1; d >= 0; --d) {
        if (steps >= (1 << d)) {
            node = ancestors[node][d];
            steps -= (1 << d);
            if (node == -1) break;
        }
    }
    return node;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n, m;
    cin >> n >> m;
    
    tree_types.resize(n);
    for (int i = 0; i < n; ++i) {
        cin >> tree_types[i];
    }
    
    graph.resize(n);
    for (int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        a--; b--;
        graph[a].emplace_back(b, c);
        graph[b].emplace_back(a, c);
    }
    
    dijkstra(0, n);
    
    int k;
    cin >> k;
    while (k--) {
        int x, d, p;
        cin >> x >> d >> p;
        x--;
        
        int r = depths[x] - d;
        int y = x;
        
        if (r > 0) {
            y = find_ancestor(x, r);
        }
        
        ll cost = min_costs[x] - min_costs[y];
        if (p < min_costs[y]) {
            cost = min_costs[x] - p;
        }
        
        cout << cost << '\n';
    }
    
    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 33948
final_rank: 1

code_snippet: // AOJ #2764 Travel Support

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

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct State { ll cost; int days, city, parent; };
 
int N;
vector<int> popArr;
 
struct StateCompare {
    bool operator()(const State &a, const State &b) const {
        if(a.cost != b.cost) return a.cost > b.cost;
        if(a.days != b.days) return a.days > b.days;
        int pa = (a.parent == -1 ? -1 : popArr[a.parent-1]);
        int pb = (b.parent == -1 ? -1 : popArr[b.parent-1]);
        return pa > pb;
    }
};
 
struct Edge { int to, cost; };
 
int main() {
    N = Cin();
    int M = Cin();
    popArr.resize(N);
    for (int i=0; i<N; i++) popArr[i] = Cin();
 
    vector<vector<Edge>> graph(N+1);
    for (int i=0; i<M; i++){
        int a = Cin(), b = Cin(), c = Cin();
        graph[a].push_back({b,c});
        graph[b].push_back({a,c});
    }
 
    const ll INF = 1LL << 60;
    vector<ll> bestCost(N+1, INF);
    vector<int> bestDays(N+1, INT_MAX);
    vector<int> bestParent(N+1, -1);
    bestCost[1] = 0;
    bestDays[1] = 0;
    bestParent[1] = -1;
 
    priority_queue<State, vector<State>, StateCompare> pq;
    pq.push({0,0,1,-1});
 
    while(!pq.empty()){
        State st = pq.top(); pq.pop();
        int cur = st.city;
        if(st.cost != bestCost[cur] || st.days != bestDays[cur]) continue;
 
        for(auto &e : graph[cur]){
            int nxt = e.to;
            ll nc = st.cost + e.cost;
            int nd = st.days + 1;
            int candidateParent = cur;
            bool update = false;
            if(nc < bestCost[nxt]) update = true;
            else if(nc == bestCost[nxt]){
                if(nd < bestDays[nxt]) update = true;
                else if(nd == bestDays[nxt]){
                    int candPop = popArr[candidateParent-1];
                    int currPop = (bestParent[nxt] == -1 ? INT_MAX : popArr[bestParent[nxt]-1]);
                    if(candPop < currPop)
                        update = true;
                }
            }
            if(update){
                bestCost[nxt] = nc;
                bestDays[nxt] = nd;
                bestParent[nxt] = candidateParent;
                pq.push({nc, nd, nxt, candidateParent});
            }
        }
    }
 
    vector<int> depth(N+1, 0);
    for (int i=1; i<=N; i++) depth[i] = bestDays[i];
    vector<int> edgeCost(N+1, 0);
    for (int i=2; i<=N; i++){
        if(bestParent[i] != -1) edgeCost[i] = (int)(bestCost[i] - bestCost[bestParent[i]]);
    }
 
    int maxP = 0;
    while((1 << maxP) <= N) maxP++;
    vector<vector<int>> up(maxP, vector<int>(N+1, -1));
    vector<vector<ll>> sumCost(maxP, vector<ll>(N+1, 0));
    for (int i=1; i<=N; i++){
        up[0][i] = (bestParent[i] == -1 ? 0 : bestParent[i]);
        sumCost[0][i] = (i==1 ? 0 : edgeCost[i]);
    }
    for (int p=1; p<maxP; p++){
        for (int i=1; i<=N; i++){
            int mid = up[p-1][i];
            up[p][i] = (mid==0 ? 0 : up[p-1][mid]);
            sumCost[p][i] = sumCost[p-1][i] + (mid==0 ? 0 : sumCost[p-1][mid]);
        }
    }
    auto getSum = [&](int x, int k) -> ll {
        ll s = 0;
        int cur = x;
        for (int p = 0; p < maxP; p++){
            if(k & (1 << p)){
                s += sumCost[p][cur];
                cur = up[p][cur];
                if(cur==0) break;
            }
        }
        return s;
    };
 
    int Q = Cin();
    for (int i=0; i<Q; i++){
        int x = Cin(), d = Cin(), pSub = Cin();
        if(x==1){
            Cout(0);
            continue;
        }
        int L = depth[x];
        int preCount = (L > d ? L - d : 0);
        ll cost_pre = getSum(x, preCount);
        ll total = getSum(x, L);
        ll cost_post = total - cost_pre;
        ll extra = 0;
        if((ll)pSub < cost_post) extra = cost_post - pSub;
        ll ans = cost_pre + extra;
        Cout(ans);
    }
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 45852
final_rank: 3

code_snippet: // AOJ #2764 Travel Support

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

struct State { ll cost; int days, city, parent; };
 
int N;
vector<int> popArr;
 
struct StateCompare {
    bool operator()(const State &a, const State &b) const {
        if(a.cost != b.cost) return a.cost > b.cost;
        if(a.days != b.days) return a.days > b.days;
        int pa = (a.parent == -1 ? -1 : popArr[a.parent-1]);
        int pb = (b.parent == -1 ? -1 : popArr[b.parent-1]);
        return pa > pb;
    }
};
 
struct Edge { int to, cost; };
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int M;
    cin >> N >> M;
    popArr.resize(N);
    for (int i=0; i<N; i++) cin >> popArr[i];
 
    vector<vector<Edge>> graph(N+1);
    for (int i=0; i<M; i++){
        int a, b, c;
        cin >> a >> b >> c;
        graph[a].push_back({b,c});
        graph[b].push_back({a,c});
    }
 
    const ll INF = 1LL << 60;
    vector<ll> bestCost(N+1, INF);
    vector<int> bestDays(N+1, INT_MAX);
    vector<int> bestParent(N+1, -1);
    bestCost[1] = 0;
    bestDays[1] = 0;
    bestParent[1] = -1;
 
    priority_queue<State, vector<State>, StateCompare> pq;
    pq.push({0,0,1,-1});
 
    while(!pq.empty()){
        State st = pq.top(); pq.pop();
        int cur = st.city;
        if(st.cost != bestCost[cur] || st.days != bestDays[cur]) continue;
 
        for(auto &e : graph[cur]){
            int nxt = e.to;
            ll nc = st.cost + e.cost;
            int nd = st.days + 1;
            int candidateParent = cur;
            bool update = false;
            if(nc < bestCost[nxt]) update = true;
            else if(nc == bestCost[nxt]){
                if(nd < bestDays[nxt]) update = true;
                else if(nd == bestDays[nxt]){
                    int candPop = popArr[candidateParent-1];
                    int currPop = (bestParent[nxt] == -1 ? INT_MAX : popArr[bestParent[nxt]-1]);
                    if(candPop < currPop)
                        update = true;
                }
            }
            if(update){
                bestCost[nxt] = nc;
                bestDays[nxt] = nd;
                bestParent[nxt] = candidateParent;
                pq.push({nc, nd, nxt, candidateParent});
            }
        }
    }
 
    vector<int> depth(N+1, 0);
    for (int i=1; i<=N; i++) depth[i] = bestDays[i];
    vector<int> edgeCost(N+1, 0);
    for (int i=2; i<=N; i++){
        if(bestParent[i] != -1) edgeCost[i] = (int)(bestCost[i] - bestCost[bestParent[i]]);
    }
 
    int maxP = 0;
    while((1 << maxP) <= N) maxP++;
    vector<vector<int>> up(maxP, vector<int>(N+1, -1));
    vector<vector<ll>> sumCost(maxP, vector<ll>(N+1, 0));
    for (int i=1; i<=N; i++){
        up[0][i] = (bestParent[i] == -1 ? 0 : bestParent[i]);
        sumCost[0][i] = (i==1 ? 0 : edgeCost[i]);
    }
    for (int p=1; p<maxP; p++){
        for (int i=1; i<=N; i++){
            int mid = up[p-1][i];
            up[p][i] = (mid==0 ? 0 : up[p-1][mid]);
            sumCost[p][i] = sumCost[p-1][i] + (mid==0 ? 0 : sumCost[p-1][mid]);
        }
    }
    auto getSum = [&](int x, int k) -> ll {
        ll s = 0;
        int cur = x;
        for (int p = 0; p < maxP; p++){
            if(k & (1 << p)){
                s += sumCost[p][cur];
                cur = up[p][cur];
                if(cur==0) break;
            }
        }
        return s;
    };
 
    int Q;
    cin >> Q;
    for (int i=0; i<Q; i++){
        int x, d, pSub;
        cin >> x >> d >> pSub;
        if(x==1){
            cout << 0 << endl;
            continue;
        }
        int L = depth[x];
        int preCount = (L > d ? L - d : 0);
        ll cost_pre = getSum(x, preCount);
        ll total = getSum(x, L);
        ll cost_post = total - cost_pre;
        ll extra = 0;
        if((ll)pSub < cost_post) extra = cost_post - pSub;
        ll ans = cost_pre + extra;
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 45432
final_rank: 9

code_snippet: #include <iostream>
#include <tuple>
#include <queue>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
#pragma warning (disable: 4996)

// Main Variables
long long N, T[1 << 19];
long long M, A[1 << 19], B[1 << 19], C[1 << 19];
long long K, X[1 << 19], D[1 << 19], P[1 << 19];
vector<pair<long long, long long>> G[1 << 19];
vector<int> H[1 << 19];
pair<long long, long long> Dist[1 << 19];
priority_queue<tuple<long long, long long, long long>, vector<tuple<long long, long long, long long>>, greater<tuple<long long, long long, long long>>> Q;

// LCA Variables
long long Par[1 << 19][22];
long long Depth[1 << 19];
bool Used[1 << 19];

void dfs(int pos, int dep) {
	Depth[pos] = dep;
	for (int to : H[pos]) dfs(to, dep + 1);
}

int prevs(int pos, int x) {
	for (int i = 20; i >= 0; i--) {
		if (x >= (1 << i)) { x -= (1 << i); pos = Par[pos][i]; }
	}
	return pos;
}

int main() {
	// Step 1. Input
	scanf("%lld%lld", &N, &M);
	for (int i = 1; i <= N; i++) scanf("%lld", &T[i]);
	for (int i = 1; i <= M; i++) scanf("%lld%lld%lld", &A[i], &B[i], &C[i]);
	scanf("%lld", &K);
	for (int i = 1; i <= K; i++) scanf("%lld%lld%lld", &X[i], &D[i], &P[i]);

	// Step 2. Make Graph
	for (int i = 1; i <= M; 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 <= N; i++) Dist[i] = make_pair((1LL << 60), -1);
	Q.push(make_tuple(0, 0, 1));
	Dist[1] = make_pair(0, 0);

	// Step 3A. Dijkstra
	while (!Q.empty()) {
		long long pos = get<2>(Q.top());
		long long cost1 = get<0>(Q.top());
		long long cost2 = get<1>(Q.top()); Q.pop();
		if (Used[pos] == true) continue;
		Used[pos] = true;
		for (int i = 0; i < G[pos].size(); i++) {
			long long to = G[pos][i].first;
			long long nex_cost1 = cost1 + G[pos][i].second;
			long long nex_cost2 = cost2 + 1;
			if (Dist[to] > make_pair(nex_cost1, nex_cost2)) {
				Dist[to] = make_pair(nex_cost1, nex_cost2);
				Q.push(make_tuple(nex_cost1, nex_cost2, to));
			}
		}
	}

	// Step 3B. Get Prev
	for (int i = 2; i <= N; i++) {
		pair<long long, long long> minid = make_pair((1LL << 60), (1LL << 60));
		for (int j = 0; j < G[i].size(); j++) {
			long long to = G[i][j].first;
			long long bef_cost1 = Dist[i].first - G[i][j].second;
			long long bef_cost2 = Dist[i].second - 1;
			if (Dist[to] == make_pair(bef_cost1, bef_cost2)) {
				minid = min(minid, make_pair(T[to], to));
			}
		}
		Par[i][0] = minid.second;
	}

	// Step 4. LCA Init
	for (int d = 1; d <= 20; d++) {
		for (int i = 1; i <= N; i++) Par[i][d] = Par[Par[i][d - 1]][d - 1];
	}
	for (int i = 2; i <= N; i++) H[Par[i][0]].push_back(i);
	dfs(1, 0);

	// Step 5. Answer Query
	for (int i = 1; i <= K; i++) {
		long long Dist1 = get<0>(Dist[X[i]]);
		long long Dist2 = 0;
		if (Depth[X[i]] > D[i]) {
			int pos = prevs(X[i], Depth[X[i]] - D[i]);
			Dist2 = get<0>(Dist[X[i]]) - get<0>(Dist[pos]);
		}
		long long Answer = max(Dist2, Dist1 - P[i]);
		printf("%lld\n", Answer);
	}
	return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 99928
final_rank: 14

code_snippet: #include <iostream>
#include <tuple>
#include <queue>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
#pragma warning (disable: 4996)

// Main Variables
long long N, T[1 << 19];
long long M, A[1 << 19], B[1 << 19], C[1 << 19];
long long K, X[1 << 19], D[1 << 19], P[1 << 19];
long long Prev[1 << 19];
vector<pair<long long, long long>> G[1 << 19];
vector<int> H[1 << 19];
tuple<long long, long long, long long> Dist[1 << 19];
priority_queue<tuple<long long, long long, long long, long long>, vector<tuple<long long, long long, long long, long long>>, greater<tuple<long long, long long, long long, long long>>> Q;

// LCA Variables
long long Par[1 << 19][22];
long long Depth[1 << 19];
bool Used[1 << 19];

void dfs(int pos, int dep) {
	Depth[pos] = dep;
	for (int to : H[pos]) dfs(to, dep + 1);
}

int prevs(int pos, int x) {
	for (int i = 20; i >= 0; i--) {
		if (x >= (1 << i)) { x -= (1 << i); pos = Par[pos][i]; }
	}
	return pos;
}

int main() {
	// Step 1. Input
	scanf("%lld%lld", &N, &M);
	for (int i = 1; i <= N; i++) scanf("%lld", &T[i]);
	for (int i = 1; i <= M; i++) scanf("%lld%lld%lld", &A[i], &B[i], &C[i]);
	scanf("%lld", &K);
	for (int i = 1; i <= K; i++) scanf("%lld%lld%lld", &X[i], &D[i], &P[i]);

	// Step 2. Make Graph
	for (int i = 1; i <= M; 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 <= N; i++) Dist[i] = make_tuple((1LL << 60), -1, -1);
	Q.push(make_tuple(0, 0, (1LL << 60), 1));
	Dist[1] = make_tuple(0, 0, (1LL << 60));

	// Step 3. Dijkstra
	while (!Q.empty()) {
		long long pos = get<3>(Q.top());
		long long cost1 = get<0>(Q.top());
		long long cost2 = get<1>(Q.top());
		long long cost3 = get<2>(Q.top()); Q.pop();
		if (Used[pos] == true) continue;
		Used[pos] = true;
		for (int i = 0; i < G[pos].size(); i++) {
			long long to = G[pos][i].first;
			long long nex_cost1 = cost1 + G[pos][i].second;
			long long nex_cost2 = cost2 + 1;
			long long nex_cost3 = min(cost3, T[pos]);
			if (Dist[to] > make_tuple(nex_cost1, nex_cost2, nex_cost3)) {
				Dist[to] = make_tuple(nex_cost1, nex_cost2, nex_cost3);
				Prev[to] = pos;
				Q.push(make_tuple(nex_cost1, nex_cost2, nex_cost3, to));
			}
		}
	}

	// Step 4. LCA Init
	for (int i = 1; i <= N; i++) Par[i][0] = Prev[i];
	for (int d = 1; d <= 20; d++) {
		for (int i = 1; i <= N; i++) Par[i][d] = Par[Par[i][d - 1]][d - 1];
	}
	for (int i = 2; i <= N; i++) H[Prev[i]].push_back(i);
	dfs(1, 0);

	// Step 5. Answer Query
	for (int i = 1; i <= K; i++) {
		long long Dist1 = get<0>(Dist[X[i]]);
		long long Dist2 = 0;
		if (Depth[X[i]] > D[i]) {
			int pos = prevs(X[i], Depth[X[i]] - D[i]);
			Dist2 = get<0>(Dist[X[i]]) - get<0>(Dist[pos]);
		}
		long long Answer = max(Dist2, Dist1 - P[i]);
		printf("%lld\n", Answer);
	}
	return 0;
}
accuracy: 0.6984126984126984
time_ms: 170
memory_kb: 102900
final_rank: 20

code_snippet: #include <iostream>
#include <tuple>
#include <queue>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
#pragma warning (disable: 4996)

// Main Variables
long long N, T[1 << 19];
long long M, A[1 << 19], B[1 << 19], C[1 << 19];
long long K, X[1 << 19], D[1 << 19], P[1 << 19];
long long Prev[1 << 19];
vector<pair<long long, long long>> G[1 << 19];
vector<int> H[1 << 19];
tuple<long long, long long, long long> Dist[1 << 19];
priority_queue<tuple<long long, long long, long long, long long>, vector<tuple<long long, long long, long long, long long>>, greater<tuple<long long, long long, long long, long long>>> Q;

// LCA Variables
long long Par[1 << 19][22];
long long Depth[1 << 19];
bool Used[1 << 19];

void dfs(int pos, int dep) {
	Depth[pos] = dep;
	for (int to : H[pos]) dfs(to, dep + 1);
}

int prevs(int pos, int x) {
	for (int i = 20; i >= 0; i--) {
		if (x >= (1 << i)) { x -= (1 << i); pos = Par[pos][i]; }
	}
	return pos;
}

int main() {
	// Step 1. Input
	scanf("%lld%lld", &N, &M);
	for (int i = 1; i <= N; i++) scanf("%lld", &T[i]);
	for (int i = 1; i <= M; i++) scanf("%lld%lld%lld", &A[i], &B[i], &C[i]);
	scanf("%lld", &K);
	for (int i = 1; i <= K; i++) scanf("%lld%lld%lld", &X[i], &D[i], &P[i]);

	// Step 2. Make Graph
	for (int i = 1; i <= M; 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 <= N; i++) Dist[i] = make_tuple((1LL << 60), -1, -1);
	Q.push(make_tuple(0, 0, 0, 1));
	Dist[1] = make_tuple(0, 0, 0);

	// Step 3. Dijkstra
	while (!Q.empty()) {
		long long pos = get<3>(Q.top());
		long long cost1 = get<0>(Q.top());
		long long cost2 = get<1>(Q.top());
		long long cost3 = get<2>(Q.top()); Q.pop();
		if (Used[pos] == true) continue;
		Used[pos] = true;
		for (int i = 0; i < G[pos].size(); i++) {
			long long to = G[pos][i].first;
			long long nex_cost1 = cost1 + G[pos][i].second;
			long long nex_cost2 = cost2 + 1;
			long long nex_cost3 = cost3 + T[to];
			if (Dist[to] > make_tuple(nex_cost1, nex_cost2, nex_cost3)) {
				Dist[to] = make_tuple(nex_cost1, nex_cost2, nex_cost3);
				Prev[to] = pos;
				Q.push(make_tuple(nex_cost1, nex_cost2, nex_cost3, to));
			}
		}
	}

	// Step 4. LCA Init
	for (int i = 1; i <= N; i++) Par[i][0] = Prev[i];
	for (int d = 1; d <= 20; d++) {
		for (int i = 1; i <= N; i++) Par[i][d] = Par[Par[i][d - 1]][d - 1];
	}
	for (int i = 2; i <= N; i++) H[Prev[i]].push_back(i);
	dfs(1, 0);

	// Step 5. Answer Query
	for (int i = 1; i <= K; i++) {
		long long Dist1 = get<0>(Dist[X[i]]);
		long long Dist2 = 0;
		if (Depth[X[i]] > D[i]) {
			int pos = prevs(X[i], Depth[X[i]] - D[i]);
			Dist2 = get<0>(Dist[X[i]]) - get<0>(Dist[pos]);
		}
		long long Answer = max(Dist2, Dist1 - P[i]);
		printf("%lld\n", Answer);
	}
	return 0;
}
accuracy: 0.6984126984126984
time_ms: 170
memory_kb: 102632
final_rank: 19

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

int main(){
  using ll = long long;
  int N, M;
  cin >> N >> M;
  vector<int> T(N);
  for(int i = 0; i < N; ++i)
    cin >> T[i];
  vector<vector<pair<int,int>>> G(N);
  for(int i = 0; i < M; ++i){
    int a, b, c;
    cin >> a >> b >> c;
    --a,--b;
    G[a].emplace_back(c,b);
    G[b].emplace_back(c,a);
  }
  int K;
  cin >> K;
  vector<int> X(K), D(K), P(K);
  for(int i = 0; i < K; ++i){
    cin >> X[i] >> D[i] >> P[i];
    --X[i];
  }
  priority_queue<array<ll,3>,vector<array<ll,3>>,greater<>> pq;
  pq.push({0,0,0});
  const ll INF = 1e18;
  vector<ll> cost(N,INF), day(N,INF), from(N,-1);
  cost[0] = 0;
  day[0] = 0;
  from[0] = 0;
  auto update = [&](int v, ll c, int d, int f){
                  if(cost[v] < c) return false;
                  if(cost[v] > c){
                    cost[v] = c;
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(day[v] < d) return false;
                  if(day[v] > d){
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(from[v] < 0 or T[from[v]] > T[f]){
                    from[v] = f;
                    return true;
                  }
                  return false;
                };

  while(pq.size()){
    auto p = pq.top();
    pq.pop();
    ll c = p[0], d = p[1], v = p[2];
    if(cost[v] != c or day[v] != d) continue;
    for(auto e : G[v]){
      ll c_ = c + e.first, d_ = d + 1, v_ = e.second;
      if(update(v_,c_,d_,v)){
        pq.push({c_,d_,v_});
      }
    }
  }
  // for(int i = 0; i < N; ++i){
  //   printf("v = %d, cost = %lld, day = %lld, from = %lld\n",i,cost[i],day[i],from[i]);
  // }

  vector<vector<int>> nex(N,vector<int>(25,-1));
  for(int i = 0; i < N; ++i){
    nex[i][0] = from[i];
  }
  for(int i = 1; i < 25; ++i){
    for(int j = 0; j < N; ++j){
      nex[j][i] = nex[nex[j][i-1]][i-1];
    }
  }
  for(int i = 0; i < K; ++i){
    int x = X[i], d = D[i], p = P[i];
    if(day[x] <= d){
      cout << max(0LL,cost[x]-p) << "\n";
      continue;
    }
    ll ans = cost[x];
    int v = x;
    for(int j = 24; j >= 0; --j){
      if(day[nex[v][j]] > d){
        v = nex[v][j];
      }
    }
    if(day[v] > d){
      v = nex[v][0];
    }
    ans -= cost[v];
    ans += max(0LL,cost[v]-p);
    cout << ans << "\n";
  }
}
accuracy: 1
time_ms: 480
memory_kb: 38000
final_rank: 13

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

int main(){
  using ll = long long;
  int N, M;
  cin >> N >> M;
  vector<int> T(N);
  for(int i = 0; i < N; ++i)
    cin >> T[i];
  vector<vector<pair<int,int>>> G(N);
  for(int i = 0; i < M; ++i){
    int a, b, c;
    cin >> a >> b >> c;
    --a,--b;
    G[a].emplace_back(c,b);
    G[b].emplace_back(c,a);
  }
  int K;
  cin >> K;
  vector<int> X(K), D(K), P(K);
  for(int i = 0; i < K; ++i){
    cin >> X[i] >> D[i] >> P[i];
    --X[i];
  }
  priority_queue<array<ll,3>,vector<array<ll,3>>,greater<>> pq;
  pq.push({0,0,0});
  const ll INF = 1e18;
  vector<ll> cost(N,INF), day(N,INF), from(N,-1);
  cost[0] = 0;
  day[0] = 0;
  from[0] = 0;
  auto update = [&](int v, ll c, int d, int f){
                  if(cost[v] < c) return false;
                  if(cost[v] > c){
                    cost[v] = c;
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(day[v] > d){
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(from[v] < 0 or T[from[v]] > T[f]){
                    from[v] = f;
                    return true;
                  }
                  return false;
                };

  while(pq.size()){
    auto p = pq.top();
    pq.pop();
    ll c = p[0], d = p[1], v = p[2];
    if(cost[v] != c or day[v] != d) continue;
    for(auto e : G[v]){
      ll c_ = c + e.first, d_ = d + 1, v_ = e.second;
      if(update(v_,c_,d_,v)){
        pq.push({c_,d_,v_});
      }
    }
  }
  // for(int i = 0; i < N; ++i){
  //   printf("v = %d, cost = %lld, day = %lld, from = %lld\n",i,cost[i],day[i],from[i]);
  // }

  vector<vector<int>> nex(N,vector<int>(25,-1));
  for(int i = 0; i < N; ++i){
    nex[i][0] = from[i];
  }
  for(int i = 1; i < 25; ++i){
    for(int j = 0; j < N; ++j){
      nex[j][i] = nex[nex[j][i-1]][i-1];
    }
  }
  for(int i = 0; i < K; ++i){
    int x = X[i], d = D[i], p = P[i];
    if(day[x] <= d){
      cout << max(0LL,cost[x]-p) << "\n";
      continue;
    }
    ll ans = cost[x];
    int v = x;
    for(int j = 24; j >= 0; --j){
      if(day[nex[v][j]] > d){
        v = nex[v][j];
      }
    }
    if(day[v] > d){
      v = nex[v][0];
    }
    ans -= cost[v];
    ans += max(0LL,cost[v]-p);
    cout << ans << "\n";
  }
}
accuracy: 0.6984126984126984
time_ms: 490
memory_kb: 38164
final_rank: 18

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

int main(){
  using ll = long long;
  int N, M;
  cin >> N >> M;
  vector<int> T(N);
  for(int i = 0; i < N; ++i)
    cin >> T[i];
  vector<vector<pair<int,int>>> G(N);
  for(int i = 0; i < M; ++i){
    int a, b, c;
    cin >> a >> b >> c;
    --a,--b;
    G[a].emplace_back(c,b);
    G[b].emplace_back(c,a);
  }
  int K;
  cin >> K;
  vector<int> X(K), D(K), P(K);
  for(int i = 0; i < K; ++i){
    cin >> X[i] >> D[i] >> P[i];
    --X[i];
  }
  priority_queue<array<ll,3>,vector<array<ll,3>>,greater<>> pq;
  pq.push({0,0,0});
  const ll INF = 1e18;
  vector<ll> cost(N,INF), day(N,INF), from(N,-1);
  cost[0] = 0;
  day[0] = 0;
  from[0] = 0;
  auto update = [&](int v, ll c, int d, int f){
                  if(cost[v] < c) return false;
                  if(cost[v] > c){
                    cost[v] = c;
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(day[v] > d){
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(from[v] < 0 or T[from[v]] > T[f]){
                    from[v] = f;
                    return true;
                  }
                  return false;
                };

  while(pq.size()){
    auto p = pq.top();
    pq.pop();
    ll c = p[0], d = p[1], v = p[2];
    if(cost[v] < c) continue;
    for(auto e : G[v]){
      ll c_ = c + e.first, d_ = d + 1, v_ = e.second;
      if(update(v_,c_,d_,v)){
        pq.push({c_,d_,v_});
      }
    }
  }
  // for(int i = 0; i < N; ++i){
  //   printf("v = %d, cost = %lld, day = %lld, from = %lld\n",i,cost[i],day[i],from[i]);
  // }

  vector<vector<int>> nex(N,vector<int>(25,-1));
  for(int i = 0; i < N; ++i){
    nex[i][0] = from[i];
  }
  for(int i = 1; i < 25; ++i){
    for(int j = 0; j < N; ++j){
      nex[j][i] = nex[nex[j][i-1]][i-1];
    }
  }
  for(int i = 0; i < K; ++i){
    int x = X[i], d = D[i], p = P[i];
    if(day[x] <= d){
      cout << max(0LL,cost[x]-p) << "\n";
      continue;
    }
    long long ans = cost[x];
    int v = x;
    for(int j = 24; j >= 0; --j){
      if(day[nex[v][j]] > d){
        v = nex[v][j];
      }
    }
    if(day[v] > d){
      v = nex[v][0];
    }
    ans -= cost[v];
    ans += max(0LL,cost[v]-p);
    cout << ans << "\n";
  }
}
accuracy: 0.6984126984126984
time_ms: 480
memory_kb: 38164
final_rank: 17

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

int main(){
  using ll = long long;
  int N, M;
  cin >> N >> M;
  vector<int> T(N);
  for(int i = 0; i < N; ++i)
    cin >> T[i];
  vector<vector<pair<int,int>>> G(N);
  for(int i = 0; i < M; ++i){
    int a, b, c;
    cin >> a >> b >> c;
    --a,--b;
    G[a].emplace_back(c,b);
    G[b].emplace_back(c,a);
  }
  int K;
  cin >> K;
  vector<int> X(K), D(K), P(K);
  for(int i = 0; i < K; ++i){
    cin >> X[i] >> D[i] >> P[i];
    --X[i];
  }
  priority_queue<array<ll,3>,vector<array<ll,3>>,greater<>> pq;
  pq.push({0,0,0});
  const ll INF = 1e18;
  vector<ll> cost(N,INF), day(N,INF), from(N,-1);
  cost[0] = 0;
  day[0] = 0;
  from[0] = 0;
  auto update = [&](int v, ll c, int d, int f){
                  if(cost[v] < c) return false;
                  if(cost[v] > c){
                    cost[v] = c;
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(day[v] > d){
                    day[v] = d;
                    from[v] = f;
                    return true;
                  }
                  if(from[v] < 0 or T[from[v]] > T[f]){
                    from[v] = f;
                    return true;
                  }
                  return false;
                };

  while(pq.size()){
    auto p = pq.top();
    pq.pop();
    ll c = p[0], d = p[1], v = p[2];
    if(cost[v] < c) continue;
    for(auto e : G[v]){
      ll c_ = c + e.first, d_ = d + 1, v_ = e.second;
      if(update(v_,c_,d_,v)){
        pq.push({c_,d_,v_});
      }
    }
  }
  // for(int i = 0; i < N; ++i){
  //   printf("v = %d, cost = %lld, day = %lld, from = %lld\n",i,cost[i],day[i],from[i]);
  // }

  vector<vector<int>> nex(N,vector<int>(20,-1));
  for(int i = 0; i < N; ++i){
    nex[i][0] = from[i];
  }
  for(int i = 1; i < 20; ++i){
    for(int j = 0; j < N; ++j){
      nex[j][i] = nex[nex[j][i-1]][i-1];
    }
  }
  for(int i = 0; i < K; ++i){
    int x = X[i], d = D[i], p = P[i];
    if(day[x] <= d){
      cout << max(0LL,cost[x]-p) << "\n";
      continue;
    }
    long long ans = cost[x];
    int v = x;
    for(int j = 19; j >= 0; --j){
      if(day[nex[v][j]] > d){
        v = nex[v][j];
      }
    }
    if(day[v] > d){
      v = nex[v][0];
    }
    ans -= cost[v];
    ans += max(0LL,cost[v]-p);
    cout << ans << "\n";
  }
}
accuracy: 0.6984126984126984
time_ms: 480
memory_kb: 36340
final_rank: 16

code_snippet: #include "iostream"
#include "random"
#include "string"
#include "bitset"
#include "algorithm"
#include "map"
#include "queue"
#include "list"
#include "set"
#include "climits"
#include "iomanip"
#include "stack"
#include "functional"

using namespace std;
using ll = long long int;
using PII = pair<ll, ll>;

struct Edge {
	int to, cost;
	Edge(int a, int b) {
		to = a;
		cost = b;
		return;
	}
};

struct Node {
	int num, cost, day;
	bool operator<(const Node&n)const {
		return make_pair(cost, day) < make_pair(n.cost, n.day);
	}
	bool operator>(const Node&n)const {
		return make_pair(cost, day)>make_pair(n.cost, n.day);
	}
	Node(int a, int b, int c) {
		num = a, cost = b, day = c;
		return;
	}
};

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

	int N, M;
	cin >> N >> M;
	vector<long long int>num(N);
	for (auto &i : num)cin >> i;
	vector<vector<Edge>>edge(N);
	for (int i = 0; i < M; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		a--;
		b--;
		edge[a].push_back(Edge(b, c));
		edge[b].push_back(Edge(a, c));
	}
	vector<pair<int, int>>dist(N, { 1000000000,1000000000 });
	dist[0] = make_pair( 0,0 );
	priority_queue<Node, vector<Node>, greater<Node>>PQ;
	PQ.push(Node(0, 0, 0));
	while (!PQ.empty()) {
		int cn = PQ.top().num;
		int c = PQ.top().cost;
		int cd = PQ.top().day;
		PQ.pop();
		for (auto i : edge[cn]) {
			if (dist[i.to] > make_pair(c + i.cost, cd + 1)) {
				dist[i.to] = make_pair(c + i.cost, cd + 1);
				PQ.push(Node(i.to, dist[i.to].first, dist[i.to].second));
			}
		}
	}
	int K;
	cin >> K;
	vector<vector<int>>tapi(N, vector<int>(20, -1));
	for (int i = 1; i < N; i++) {
		int nx = -1;
		for (auto j : edge[i]) {
			if (dist[j.to].first + j.cost == dist[i].first&&dist[j.to].second + 1 == dist[i].second) {
				if (nx == -1)nx = j.to;
				else if (num[nx] > num[j.to])nx = j.to;
			}
		}
		if (nx != -1) {
			tapi[i][0] = nx;
		}
	}
	for (int j = 1; j < 20; j++) {
		for (int i = 0; i < N; i++) {
			if (tapi[i][j - 1] == -1)continue;
			tapi[i][j] = tapi[tapi[i][j - 1]][j - 1];
		}
	}
	while (K--) {
		int a, b, c;
		cin >> a >> b >> c;
		a--;
		int step = max(0, dist[a].second - b);
		int ans = dist[a].first;
		int node = a;
		for (int i = 0; i < 20; i++) {
			if ((step >> i) & 1) {
				node = tapi[node][i];
			}
		}
		ans -= dist[node].first;
		ans += max(0, dist[node].first - c);
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 410
memory_kb: 32588
final_rank: 10

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100005

struct Edge{
	Edge(int arg_to,ll arg_cost){
		to = arg_to;
		cost = arg_cost;
	}
	int to;
	ll cost;
};

struct Info{

	int start,day,pay;
};

struct State{

	State(int arg_node_id,int arg_sum_date,int arg_sum_cost){
		node_id = arg_node_id;
		sum_date = arg_sum_date;
		sum_cost = arg_sum_cost;
	}
	bool operator<(const struct State &arg) const{

		if(sum_cost != arg.sum_cost){

			return sum_cost > arg.sum_cost; //総コストが異なるなら昇順(PQ)
		}else{

			return sum_date > arg.sum_date; //総コストが同じなら、日数の総和(PQ)
		}
	}

	int node_id,sum_date,sum_cost;
};

int N,E,K;
int root; //根ノードの番号
int MAX_LOG_V = 17;
int POW[18];
int T[NUM];
int min_dist[NUM],min_date[NUM];
int parent[18][NUM];
int depth[NUM];
vector<Edge> G[NUM]; //グラフの隣接リスト表現
vector<int> Tree_G[NUM];
Info info[NUM];


//parentとdepthを再帰的に設定
void dfs(int node_id,int parent_id,int d){
	parent[0][node_id] = parent_id;
	depth[node_id] = d;
	for(int i = 0; i < Tree_G[node_id].size(); i++){
		if(Tree_G[node_id][i] != parent_id)dfs(Tree_G[node_id][i],node_id,d+1);
	}
}

//初期化
void init(){
	//parent[0]とdepthを初期化する
	dfs(root,-1,0);
	//parentを初期化する
	for(int k = 0; k + 1 < MAX_LOG_V; k++){
		for(int node_id = 0; node_id < N; node_id++){
			if(parent[k][node_id] < 0)parent[k+1][node_id] = -1; //node_idの2^k上のノードがルートノードより上なら、2^(k+1)上も同様とする
			else{
				parent[k+1][node_id] = parent[k][parent[k][node_id]];
			}
		}
	}
}


int main(){


	POW[0] = 1;
	for(int i = 1; i <= 17; i++){
		POW[i] = POW[i-1]*2;
	}

	scanf("%d %d",&N,&E);

	for(int i = 0; i < N; i++){

		scanf("%d",&T[i]);
	}

	int from,to,cost;

	for(int i = 0; i < E; i++){

		scanf("%d %d %d",&from,&to,&cost);
		from--;
		to--;

		G[from].push_back(Edge(to,cost));
		G[to].push_back(Edge(from,cost));
	}

	scanf("%d",&K);

	for(int i = 0; i < K; i++){

		scanf("%d %d %d",&info[i].start,&info[i].day,&info[i].pay);
		info[i].start--;
	}

	//ダイクストラ

	min_dist[0] = 0;
	min_date[0] = 0;

	for(int i = 1; i < N; i++){

		min_dist[i] = BIG_NUM;
		min_date[i] = BIG_NUM;
	}

	priority_queue<State> Q;
	Q.push(State(0,0,0));

	int next_node,next_cost,next_date;

	while(!Q.empty()){

		if((Q.top().sum_cost > min_dist[Q.top().node_id])
				|| (Q.top().sum_cost == min_dist[Q.top().node_id] && Q.top().sum_date > min_date[Q.top().node_id])){

			Q.pop();
		}else{

			for(int i = 0; i < G[Q.top().node_id].size(); i++){

				next_node = G[Q.top().node_id][i].to;
				next_cost = Q.top().sum_cost+G[Q.top().node_id][i].cost;
				next_date = Q.top().sum_date+1;

				if(min_dist[next_node] > next_cost){

					min_dist[next_node] = next_cost;
					min_date[next_node] = next_date;
					Q.push(State(next_node,next_date,next_cost));

				}else if(min_dist[next_node] == next_cost && min_date[next_node] > next_date){

					min_date[next_node] = next_date;
					Q.push(State(next_node,next_date,next_cost));
				}
			}
			Q.pop();
		}
	}

	int tmp_num,next;

	//最短経路の辺を張る
	for(int i = 1; i < N; i++){
		//次の節店を探し、辺を張る
		tmp_num = BIG_NUM;
		next = -1;

		for(int k = 0; k < G[i].size(); k++){
			if(min_dist[i]-G[i][k].cost == min_dist[G[i][k].to] && min_date[i] == min_date[G[i][k].to]+1){ //最短経路上

				if(tmp_num > T[G[i][k].to]){ //人口で選ぶ
					tmp_num = T[G[i][k].to];
					next = G[i][k].to;
				}
			}
		}

		if(next == -1)continue;

		Tree_G[next].push_back(i); //木は都市0をスタートとする
	}

	//木作り&ダブリング
	root = 0;
	init();

	int current_node,diff;

	for(int i = 0; i < K; i++){

		int ans = BIG_NUM;

		current_node = info[i].start;
		diff = depth[info[i].start]-info[i].day;

		for(int k = MAX_LOG_V-1; k >= 0; k--){
			if(diff >= POW[k]){ //たとえば深さの差が39なら、32+4+2+1のように、ノードを上方に移動させる

				current_node = parent[k][current_node];
				diff -= POW[k];
			}
		}

		if(current_node == -1){ //★金を貰う前に着く★

			ans = min(ans,min_dist[info[i].start]);

		}else{

			ans = min(ans,(min_dist[info[i].start]-min_dist[current_node])+max(0,min_dist[current_node]-info[i].pay));
		}

		printf("%d\n",ans);
	}

	return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 43016
final_rank: 7

code_snippet: #include <bits/stdc++.h>
  
using namespace std;
  
#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second
  
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
 
const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

#define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << endl
#define LINE cout << "line : " << __LINE__ << endl
#define dumpV(v) cout << #v << " : ["; for(auto& t : v) cout << t << ", "; cout<<"]" << endl
#define STOP assert(false)
#else
#define dump(x) ;
#define LINE     ;
#define dumpV(v);
#define STOP     ;
#endif
#define mp make_pair

namespace std{
  template<class S,class T>
  ostream &operator <<(ostream& out,const pair<S,T>& a){
    out<<'('<<a.fi<<", "<<a.se<<')';
    return out;
  }
}


const int MAX_N = 1e5+10;
const int MAX_M = 5e5+10;

int t[MAX_N];
using Edge = pair<int, ll>; // to, cost
vector<Edge> es[MAX_N];

using State = pair<ll, pii>; // cost, day, population
State StateINF = State(1e18, pii(1e9, 1e9));

bool chMin(State& a, const State& b) {
    if(a <= b) return false;
    a = b;
    return true;
}

State d[MAX_N];

int from[MAX_N]; // 経路復元

int A[MAX_N][30];

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    rep(i, n) cin >> t[i];
    rep(i, m) {
        int a, b, c;
        cin >> a >> b >> c;
        --a;
        --b;
        es[a].pb({b, (ll)c});
        es[b].pb({a, (ll)c});
    }
    from[0] = -1;
    {
        rep(i, n) d[i] = StateINF;
        int root = 0;
        using P = pair<State, int>;
        priority_queue<P, vector<P>, greater<P> > q;
        d[root] = {0LL, {0, -1}};
        q.push({d[root], root});
        while (!q.empty()) {
            auto p = q.top(); q.pop();
            int prv = p.se;
            const auto state = p.fi;
            if (d[prv] < p.fi) continue;
            for (auto& e : es[prv]) {
                int to = e.fi;
                auto nState = state;
                nState.fi += e.se;
                nState.se.fi++;
                nState.se.se = t[prv];

                if (chMin(d[to], nState)) {
                    q.push({d[to], to});
                    from[to] = prv;
                }
            }
        }
    }
    rep(i, MAX_N) rep(j, 30) A[i][j] = -1;
    rep(j, 30) rep(i, n) {
        if(j == 0) A[i][j] = from[i];
        else if(A[i][j-1] != -1) A[i][j] = A[A[i][j-1]][j-1];
    }
    // rep(i, n) {
    //     cout << i << " " << d[i].fi << " " << d[i].se.fi << " " << d[i].se.se  << " " << from[i] << " " << A[i][0] <<endl;
    // }
    // return 0;
    // LINE;
    int k;
    cin >> k;
    rep(_, k) {
        int x, D, p;
        cin >> x >> D >> p;
        --x;
        auto s = d[x];
        int day = s.se.fi;
        ll cost = s.fi;
        if(day <= D) cout << max(0LL, cost - p) << '\n';
        else {
            int now = x;
            while(d[now].se.fi > D) {
                // dump(mp(now, d[now].se.fi));
                // dump(D);
                if(A[now][0] == -1) break;
                rep(i, 20) {
                    int to = A[now][i];
                    if(to == -1) {
                        now = A[now][i-1];
                        break;
                    }
                    if(d[to].se.fi < D) {
                        now = A[now][i-1];
                        break;
                    } 
                }
            }
            assert(now >= 0 && d[now].se.fi == D);
            ll dif = cost - d[now].fi;
            // cout << now << endl;
            cout << dif + max(0LL, d[now].fi - p) << '\n';
            // LINE;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 44388
final_rank: 8

code_snippet: #include <queue>
#include <vector>
#include <iostream>
using namespace std;
const int bits = 20;
struct edge {
	int to, cost;
};
struct state {
	int pos, cost, dist, pop, par;
};
bool operator<(const state& s1, const state& s2) {
	if (s1.cost != s2.cost) return s1.cost > s2.cost;
	if (s1.dist != s2.dist) return s1.dist > s2.dist;
	return s1.pop > s2.pop;
}
int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	int N, M;
	cin >> N >> M;
	vector<int> t(N);
	for (int i = 0; i < N; ++i) cin >> t[i];
	vector<vector<edge> > G(N);
	for (int i = 0; i < M; ++i) {
		int a, b, c;
		cin >> a >> b >> c; --a, --b;
		G[a].push_back(edge{ b, c });
		G[b].push_back(edge{ a, c });
	}
	priority_queue<state> que;
	que.push(state{ 0, 0, 0, t[0], -1 });
	vector<int> p(N, -2), pc(N), days(N), costs(N);
	while (!que.empty()) {
		state u = que.top(); que.pop();
		if (p[u.pos] == -2) {
			p[u.pos] = u.par;
			days[u.pos] = u.dist;
			costs[u.pos] = u.cost;
			for (edge e : G[u.pos]) {
				if (p[e.to] == -2) {
					que.push(state{ e.to, u.cost + e.cost, u.dist + 1, t[u.pos], u.pos });
				}
			}
		}
	}
	vector<vector<int> > xp(bits, vector<int>(N));
	xp[0] = p; xp[0][0] = 0;
	for (int i = 1; i < bits; ++i) {
		for (int j = 0; j < N; ++j) {
			xp[i][j] = xp[i - 1][xp[i - 1][j]];
		}
	}
	int Q;
	cin >> Q;
	for (int i = 0; i < Q; ++i) {
		int pos, day, money;
		cin >> pos >> day >> money; --pos;
		int forward = max(days[pos] - day, 0);
		int fpos = pos;
		for (int j = bits - 1; j >= 0; --j) {
			if ((forward >> j) & 1) fpos = xp[j][fpos];
		}
		int least = costs[pos] - costs[fpos];
		int ans = least + max(costs[fpos] - money, 0);
		cout << ans << '\n';
	}
	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 35716
final_rank: 6

code_snippet: #include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <queue>
#include <cmath>
#include <cstdlib>
using namespace std;
using ll = long long int;

#define fprintf(...) void(0)

struct Edge {
    ll to, cost;
};

using Graph = vector< vector< Edge > >;

struct Elem {
    ll pos, cost, day;
    bool operator<(const Elem &e) const {
        if(cost != e.cost) return cost > e.cost;
        return day > e.day;
    }
};

const int MAX_N = 100000;
ll N, M, K;
ll popu[MAX_N + 10], x[MAX_N + 10], d[MAX_N + 10], p[MAX_N + 10];

const ll INF = 1LL << 60;
pair< Graph, vector<int> > get_tree(Graph &G) {
    // cost, days
    vector< pair<ll, ll> > state(N, make_pair(INF, INF));

    // population, prev_town
    vector< pair<ll, ll> > pre(N, make_pair(INF, -1));

    priority_queue<Elem> que;
    que.push(Elem{0, 0, 0});
    state[0] = make_pair(0, 0);

    while(que.size()) {
        Elem cur = que.top(); que.pop();
        pair<ll, ll> cur_state = make_pair(cur.cost, cur.day);

        int u = cur.pos;
        if(cur_state > state[u]) continue;

        for(auto e : G[u]) {
            int to = e.to, n_cost = cur.cost + e.cost, n_day = cur.day + 1;

            pair<ll, ll> nxt      = make_pair(n_cost, n_day);
            pair<ll, ll> pop_info = make_pair(popu[u], u);
            if(state[to] > nxt) {
                state[to] = nxt;
                pre[to] = pop_info;
                que.push(Elem{to, n_cost, n_day});
            }
            else if(state[to] == nxt) {
                if(pre[to] > pop_info) {
                    pre[to] = pop_info;
                }
            }
        }
    }

    Graph ret(N);
    vector<int> par(N, -1);
    for(int i=1; i<N; i++) {
        // the parent of i is pre[i].second
        int u = i, v = pre[i].second;

        ll cost_u = state[u].first, cost_v = state[v].first;
        ll diff = llabs(cost_u - cost_v);
        ret[u].push_back(Edge{v, diff});
        ret[v].push_back(Edge{u, diff});
        par[u] = v;
    }
    return make_pair(ret, par);
}

pair< vector<ll>, vector<ll> > get_cost_info(Graph &G) {
    vector<ll> visited(N), sum(N), days(N);

    queue<int> que;
    que.push(0);
    visited[0] = true;

    while(que.size()) {
        int cur = que.front(); que.pop();
        for(auto e : G[cur]) {
            if(visited[e.to]) continue;
            visited[e.to] = true;
            sum[e.to] = sum[cur] + e.cost;
            days[e.to] = days[cur] + 1;
            que.push(e.to);
        }
    }
    return make_pair(sum, days);
}

void solve(Graph &G, vector<int> &par) {
    vector< vector<int> > nxt(N, vector<int>(18, -1));
    vector<ll> acc_cost, days;
    tie(acc_cost, days) = get_cost_info(G);

    // 2^k table
    for(int i=0; i<N; i++) {
        fprintf(stderr, "parent of %d is %d\n", i, par[i]);
        nxt[i][0] = par[i];
    }
    for(int k=1; k<18; k++) {
        for(int i=0; i<N; i++) {
            if(nxt[i][k-1] < 0) continue;
            nxt[i][k] = nxt[ nxt[i][k-1] ][k-1];
        }
    }

    for(int i=0; i<K; i++) {
        ll need_day = days[ x[i] ];
        ll dayA = max(0LL, days[ x[i] ] - d[i]), dayB = need_day - dayA;

        ll costA = acc_cost[ x[i] ];

        // get costB
        ll rest = dayA, cur = x[i];
        for(int k=0; k<18; k++) {
            if(rest >> k & 1) {
                cur = nxt[cur][k];
            }
        }

        ll costB = acc_cost[ cur ];

        fprintf(stderr, "dayA = %lld, dayB = %lld, costA = %lld, costB = %lld\n", dayA, dayB, costA, costB);

        ll ans = costA - costB + max(0LL, costB - p[i]);
        printf("%lld\n", ans);
    }
}

int main() {
    scanf("%lld%lld", &N, &M);
    for(int i=0; i<N; i++) {
        scanf("%lld", &popu[i]);
    }

    Graph G(N);
    for(int i=0; i<M; i++) {
        int a, b, c; scanf("%d%d%d", &a, &b, &c);
        a--; b--;
        G[a].push_back(Edge{b, c});
        G[b].push_back(Edge{a, c});
    }

    scanf("%lld", &K);
    for(int i=0; i<K; i++) {
        scanf("%lld%lld%lld", &x[i], &d[i], &p[i]);
        x[i]--;
    }

    Graph H; vector<int> par;

    fprintf(stderr, "get tree!\n");
    tie(H, par) = get_tree(G);

    fprintf(stderr, "solve!\n");
    solve(H, par);
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 53072
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
#define rep(i,n) for(int i=0;i<n;i++)
#define MP make_pair
#define PB push_back
ll inf = (1LL)<<60;

ll dp[100001][20];


int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n,m;
    cin >> n >> m;
    vector<ll> t(n);
    rep(i,n)cin >> t[i];
    vector<vector<pair<int,ll> > >g(n);
    rep(i,m){
        int a,b;
        ll c;
        cin >> a >> b >> c;
        a--;
        b--;
        g[a].PB(MP(b,c));
        g[b].PB(MP(a,c));
    }
    priority_queue<pair<ll,pair<ll,int> >,vector<pair<ll,pair<ll,int> > >,greater<pair<ll,pair<ll,int> > > >pq;
    pq.push(MP((ll)0,MP((ll)0,0)));
    vector<int> parent(n);
    parent[0]=-1;
    vector<pair<ll,ll>  > place(n,MP(inf,inf));
    place[0] = MP(0,0);
    while(!pq.empty()){
        auto xxxxxxxx = pq.top();
        pq.pop();
        auto x = xxxxxxxx.first;
        auto y = xxxxxxxx.second.first;
        auto p = xxxxxxxx.second.second;
        if(make_pair(x,y) > place[p]) continue;
        for(auto& e : g[p]){
            if(MP(x+e.second,y+1)>place[e.first])continue;
            if(MP(x+e.second,y+1)==place[e.first]){
                if(t[parent[e.first]]>t[p]){
                    parent[e.first] = p;
                    pq.push(MP(x+e.second,MP(y+1,e.first)));
                }
            }else{
                place[e.first] = MP(x+e.second,y+1);
                parent[e.first] = p;
                pq.push(MP(x+e.second,MP(y+1,e.first)));
            }
        }
    }
    rep(i,n){
        rep(j,20){
            dp[i][j] = -1;
        }
    }
    rep(i,n){
        dp[i][0] = parent[i];
    }
    rep(j,19){
        rep(i,n){
            if(dp[i][j]>=0){
                dp[i][j+1] = dp[dp[i][j]][j];
            }
        }
    }
    int k;
    cin >> k;
    rep(i,k){
        int a,b;
        ll c;
        cin >> a >> b >> c;
        a--;
        ll ans = 0;
        ans = place[a].first;
        if(place[a].second<=b){
            cout << max(0LL,ans-c) << endl;
        }else{
            int now = a;
            int d = place[a].second-b;
            for(int i = 20; i>=0; i--){
                if(d < (1 << i)) continue;
                now = dp[now][i];
                d -= (1<<i);
            }
            cout << ans - min(place[now].first,c) << endl;
        }
    }

    return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 50812
final_rank: 12

code_snippet: /*
 * g.cc: 
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>

using namespace std;

/* constant */

const int MAX_N = 100000;
const int MAX_D = 20;

typedef long long ll;

const int INF = 1 << 30;
const ll LINF = 1LL << 60;

/* typedef */

typedef pair<int,int> pii;
typedef vector<pii> vpii;

struct Stat {
  ll c;
  int d, i;
  Stat() {}
  Stat(ll _c, int _d, int _i): c(_c), d(_d), i(_i) {}
  bool operator<(const Stat &s) const {
    return c > s.c || (c == s.c && d > s.d);
  }
};

/* global variables */

int ts[MAX_N];
vpii nbrs[MAX_N];
ll costs[MAX_N];
int dists[MAX_N], prts[MAX_N][MAX_D];

/* subroutines */

/* main */

int main() {
  int n, m;
  int tmp = scanf("%d%d", &n, &m);

  for (int i = 0; i < n; i++) tmp = scanf("%d", &ts[i]);

  for (int i = 0; i < m; i++) {
    int ai, bi, ci;
    tmp = scanf("%d%d%d", &ai, &bi, &ci);
    ai--, bi--;
    nbrs[ai].push_back(pii(bi, ci));
    nbrs[bi].push_back(pii(ai, ci));
  }

  for (int i = 0; i < n; i++) costs[i] = LINF;
  costs[0] = 0;
  dists[0] = 0;
  prts[0][0] = -1;

  priority_queue<Stat> q;
  q.push(Stat(0, 0, 0));

  while (! q.empty()) {
    Stat u = q.top(); q.pop();
    if (costs[u.i] != u.c || dists[u.i] != u.d) continue;

    int vd = u.d + 1;
    vpii &nbru = nbrs[u.i];

    for (vpii::iterator vit = nbru.begin(); vit != nbru.end(); vit++) {
      int &vi = vit->first;
      ll vc = u.c + vit->second;

      if (costs[vi] > vc) {
	costs[vi] = vc;
	dists[vi] = vd;
	prts[vi][0] = u.i;
	q.push(Stat(vc, vd, vi));
      }
      else if (costs[vi] == vc) {
	if (dists[vi] > vd) {
	  dists[vi] = vd;
	  prts[vi][0] = u.i;
	  q.push(Stat(vc, vd, vi));
	}
	else if (dists[vi] == vd && ts[prts[vi][0]] > ts[u.i]) {
	  prts[vi][0] = u.i;
	}
      }
    }
  }

  for (int d = 1; d < MAX_D; d++)
    for (int i = 0; i < n; i++) {
      int j = prts[i][d - 1];
      prts[i][d] = (j < 0) ? -1 : prts[j][d - 1];
    }

  int k;
  tmp = scanf("%d", &k);

  while (k--) {
    int xi, di, pi;
    tmp = scanf("%d%d%d", &xi, &di, &pi);
    xi--;

    int r = dists[xi] - di;
    int yi = xi;
    //printf("xi=%d,di=%d,pi=%d: costs=%lld,dists=%d,r=%d\n",
    //xi, di, pi, costs[xi], dists[xi], r);

    if (r > 0)
      for (int d = MAX_D - 1; d >= 0; d--)
	if (r & (1 << d)) yi = prts[yi][d];
    //printf("  yi=%d\n", yi);
    
    ll cost = costs[xi] - costs[yi];
    if (cost < costs[xi] - pi) cost = costs[xi] - pi;

    printf("%lld\n", cost);
  }
}
accuracy: 1
time_ms: 210
memory_kb: 30240
final_rank: 2

code_snippet: #include "bits/stdc++.h"
using namespace std;
vector<int>pops;
struct edge {
	int from;
	int to;
	long long int cost;
};
struct aa {
	edge frome;
	long long int cost;
	 int time;
};
class Compare {
public:
	bool operator()(const aa l, const aa r) {
		return l.cost == r.cost ?l.time==r.time?pops[l.frome.from] > pops[r.frome.from]: l.time > r.time:l.cost > r.cost;
	}
}comp;	


class Tree {
public:
	Tree(int V, int root) : V(V),revT(V), root(root), cnum(V), place(V), id(V) {
		T.resize(V);
		for (int i = 0; i < MAXLOGV; i++) {
			parent[i].resize(V);
			costs[i].resize(V);

		}
		depth.resize(V);
	}
	// u??¨v????????????
	// lca????±????????????¨????????????????????§????????°????????¨????????????
	void unite(edge& v) {
		T[v.from].push_back(v);
		revT[v.to]=(edge{ v.to,v.from,v.cost });
	}
	// init??????
	// ????????????????????????????????????????????????????????°????????¨lca????±???????????????????
	void init() {
		dfs(root, 0, 0);
		int id = 0;
		getid(root, 0, id);
	}
	// u??¨v???lca????±???????
	int lca(int u, int v) const {
		if (depth[u] > depth[v]) swap(u, v);
		for (int k = 0; k < MAXLOGV; k++) {
			if ((depth[v] - depth[u]) >> k & 1) {
				v = parent[k][v];
			}
		}
		if (u == v) return u;
		for (int k = MAXLOGV - 1; k >= 0; k--) {
			if (parent[k][u] != parent[k][v]) {
				u = parent[k][u];
				v = parent[k][v];
			}
		}
		return parent[0][u];
	}
	// u??¨v????????¢????±???????
	// edge????????????????????¨????????????????????????????????????
	int dist(int u, int v) const {
		int p = lca(u, v);
		return (depth[u] - depth[p]) + (depth[v] - depth[p]);
	}
	int dfs(int v, int p, int d) {
		parent[0][v] = p;
		costs[0][v] = revT[v].cost;
		depth[v] = d;
		cnum[v] = 0;
		for (int i = 1; i < MAXLOGV; i++) {
			parent[i][v] = parent[i - 1][parent[i - 1][v]];
			costs[i][v] = costs[i - 1][parent[i - 1][v]] + costs[i - 1][v];
		}
		for (auto e : T[v]) {
			int next = e.to;
			if (next != p) cnum[v] += dfs(next, v, d + 1);
		}
		return cnum[v] + 1;
	}

	void getid(const int v, const int p, int &nplace) {
		place[v] = nplace;
		id[nplace] = v;
		nplace++;
		for (auto e : T[v]) {
			int next = e.to;
			if (next != p) getid(next, v, nplace);
		}
	}
	static const int MAXLOGV = 20;
	// ??°???????????£??\???????????¨???
	vector<vector<edge> > T;
	vector<edge>revT;
	// ???????????°
	int V;
	// ?????????????????????
	int root;

	// ????????????
	vector<int> parent[MAXLOGV];
	vector<long long int>costs[MAXLOGV];
	// ??????????????±???
	vector<int> depth;

	//????????°
	vector<int>cnum;

	//??????
	vector<int>place;
	vector<int>id;

};

int main() {
	int N, M; cin >> N >> M;
	for (int i = 0; i < N; ++i) {
		int a; cin >> a;
		pops.push_back(a);
	}
	vector<vector<edge>>edges(N);
	for (int i = 0; i < M; ++i) {
		int a, b, c; cin >> a >> b >> c; a--; b--;
		edges[a].push_back(edge{ a,b,c });
		edges[b].push_back(edge{ b,a,c });
	}
	
	vector<aa>memo(N, aa{ edge{-1,-1,-1},static_cast<long long int>(1e18),(static_cast<int>(1e9)) });
	memo[0] = aa{ edge{-1,0,0},0,0 };
	priority_queue<aa, vector<aa>, Compare>que;
	que.push(aa{ edge{-1,0,0},0,0 });
	while (!que.empty()) {
		aa atop(que.top());
		que.pop();
		for (auto e : edges[atop.frome.to]) {
			const int next = e.to;
			const long long int nextcost = atop.cost + e.cost;
			const int nexttime = atop.time + 1;
			if (comp.operator()(memo[next],aa{ e,nextcost,nexttime })) {
				memo[next] = aa{ e,nextcost,nexttime };
				que.push(aa{ e,nextcost,nexttime });
			}
		}
	}
	Tree t(N,0);
	for (int i = 1; i < N; ++i) {
		t.unite(memo[i].frome);
	}
	t.init();
	int K; cin >> K;
	for (int i = 0; i < K; ++i) {
		long long int sum = 0;
		int x, d, p; cin >> x >> d >> p;
		x--;
		if (d >= t.depth[x]) {
			int rest = t.depth[x];
			long long int need = 0;
			int now = x;
			for (int i = 0; i < 20; ++i) {
				if (rest&(1 << i)) {
					need += t.costs[i][now];
					now = t.parent[i][now];
				}
			}
			sum += max(0ll, need -p);
		}
		else {
			int rest = t.depth[x] - d;
			long long int need = 0;
			int now = x;
			for (int i = 0; i < 20; ++i) {
				if (rest&(1 << i)) {
					need += t.costs[i][now];
					now = t.parent[i][now];
				}
			}
			sum += need;
			rest = d;
			need = 0;
			for (int i = 0; i < 20; ++i) {
				if (rest&(1 << i)) {
					need += t.costs[i][now];
					now = t.parent[i][now];
				}
			}
			sum += max(0ll, need - p);
		}
		cout << sum << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 660
memory_kb: 66080
final_rank: 15

code_snippet: /*
 * g.cc: 
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>

using namespace std;

/* constant */

const int MAX_N = 100000;
const int MAX_D = 20;

typedef long long ll;

const int INF = 1 << 30;
const ll LINF = 1LL << 60;

/* typedef */

typedef pair<int,int> pii;
typedef vector<pii> vpii;

struct Stat {
  ll c;
  int d, i;
  Stat() {}
  Stat(ll _c, int _d, int _i): c(_c), d(_d), i(_i) {}
  bool operator<(const Stat &s) const {
    return c > s.c || (c == s.c && d > s.d);
  }
};

/* global variables */

int ts[MAX_N];
vpii nbrs[MAX_N];
ll costs[MAX_N];
int dists[MAX_N], prts[MAX_N][MAX_D];

/* subroutines */

/* main */

int main() {
  int n, m;
  int tmp = scanf("%d%d", &n, &m);

  for (int i = 0; i < n; i++) tmp = scanf("%d", &ts[i]);

  for (int i = 0; i < m; i++) {
    int ai, bi, ci;
    tmp = scanf("%d%d%d", &ai, &bi, &ci);
    ai--, bi--;
    nbrs[ai].push_back(pii(bi, ci));
    nbrs[bi].push_back(pii(ai, ci));
  }

  for (int i = 0; i < n; i++) costs[i] = LINF;
  costs[0] = 0;
  dists[0] = 0;
  prts[0][0] = -1;

  priority_queue<Stat> q;
  q.push(Stat(0, 0, 0));

  while (! q.empty()) {
    Stat u = q.top(); q.pop();
    if (costs[u.i] != u.c || dists[u.i] != u.d) continue;

    int vd = u.d + 1;
    vpii &nbru = nbrs[u.i];

    for (vpii::iterator vit = nbru.begin(); vit != nbru.end(); vit++) {
      int &vi = vit->first;
      ll vc = u.c + vit->second;

      if (costs[vi] > vc) {
	costs[vi] = vc;
	dists[vi] = vd;
	prts[vi][0] = u.i;
	q.push(Stat(vc, vd, vi));
      }
      else if (costs[vi] == vc) {
	if (dists[vi] > vd) {
	  dists[vi] = vd;
	  prts[vi][0] = u.i;
	  q.push(Stat(vc, vd, vi));
	}
	else if (dists[vi] == vd && ts[prts[vi][0]] > ts[u.i]) {
	  prts[vi][0] = u.i;
	}
      }
    }
  }

  for (int d = 1; d < MAX_D; d++)
    for (int i = 0; i < n; i++) {
      int j = prts[i][d - 1];
      prts[i][d] = (j < 0) ? -1 : prts[j][d - 1];
    }

  int k;
  tmp = scanf("%d", &k);

  while (k--) {
    int xi, di, pi;
    tmp = scanf("%d%d%d", &xi, &di, &pi);
    xi--;

    int r = dists[xi] - di;
    int yi = xi;
    //printf("xi=%d,di=%d,pi=%d: costs=%lld,dists=%d,r=%d\n",
    //xi, di, pi, costs[xi], dists[xi], r);

    if (r > 0)
      for (int d = MAX_D - 1; d >= 0; d--)
	if (r & (1 << d)) yi = prts[yi][d];
    //printf("  yi=%d\n", yi);
    
    ll cost = costs[xi] - costs[yi];
    if (cost < costs[xi] - pi) cost = costs[xi] - pi;

    printf("%lld\n", cost);
  }

  return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 28244
final_rank: 5

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <cassert>
#include <string>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef pair<P,int> T;
typedef pair<T,int> F;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define SORT(x) sort((x).begin(),(x).end())
#define all(x) (x).begin(),(x).end()
#define rep(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define repn(i,a,n) for(int (i)=(a);(i)<(int)(n);(i)++)
#define EQ(a,b) (abs((a)-(b))<eps)
struct edge
{
	int to,cost;
	edge(int to,int cost):to(to),cost(cost){}
};
int N,M,K;
int t[100100];
int day[100100],dist[100100];
int x[100100],d[100100],p[100100];
int par[100100][20];
vector<edge> G[100100];
bool used[100100];
priority_queue<F,vector<F>,greater<F> > q;
int ascend(int v,int k)
{
	for(int i=19;i>=0;i--)
	{
		if(k&(1<<i))v=par[v][i];
	}
	return v;
}
int main()
{
	scanf("%d %d",&N,&M);
	for(int i=0;i<N;i++)scanf("%d",&t[i]);
	for(int i=0;i<M;i++)
	{
		int a,b,c;
		scanf("%d %d %d",&a,&b,&c);
		a--;b--;
		G[a].pb(edge(b,c));
		G[b].pb(edge(a,c));
	}
	scanf("%d",&K);
	for(int i=0;i<K;i++)
	{
		scanf("%d %d %d",&x[i],&d[i],&p[i]);
		x[i]--;
	}
	memset(used,false,sizeof(used));
	for(int i=0;i<N;i++)day[i]=INF,dist[i]=INF;
	day[0]=0;dist[0]=0;
	q.push(F(T(P(0,0),t[0]),0));
	par[0][0]=-1;
	while(!q.empty())
	{
		F a = q.top();
		q.pop();
		int v = a.sec;
		int date = a.fi.fi.sec;
		int dis = a.fi.fi.fi;
		for(int i=0;i<G[v].size();i++)
		{
			edge e = G[v][i];
			if(dist[e.to]>dis+e.cost){
				day[e.to]=date+1;
				dist[e.to]=dis+e.cost;
				par[e.to][0]=v;
				q.push(F(T(P(dist[e.to],day[e.to]),t[e.to]),e.to));
				continue;
			}
			if(dist[e.to]==dis+e.cost&&day[e.to]>date+1){
				day[e.to]=date+1;
				dist[e.to]=dis+e.cost;
				par[e.to][0]=v;
				q.push(F(T(P(dist[e.to],day[e.to]),t[e.to]),e.to));
				continue;
			}
			if(dist[e.to]==dis+e.cost&&day[e.to]==date+1&&t[par[e.to][0]]>t[v]){
				day[e.to]=date+1;
				dist[e.to]=dis+e.cost;
				par[e.to][0]=v;
				q.push(F(T(P(dist[e.to],day[e.to]),t[e.to]),e.to));
				continue;
			}
		}
	}
	/*for(int i=0;i<N;i++)
	{
		printf("%d %d %d\n",day[i],dist[i],par[i][0]);
	}*/
	for(int i=0;i<19;i++)
	{
		for(int v=0;v<N;v++)
		{
			if(par[v][i]==-1)par[v][i+1]=-1;
			else par[v][i+1]=par[par[v][i]][i];
		}
	}
	for(int i=0;i<K;i++)
	{
		if(day[x[i]]<=d[i])printf("%d\n",max(0,dist[x[i]]-p[i]));
		else
		{
			int k = day[x[i]]-d[i];
			assert(k<=day[x[i]]);
			int y = ascend(x[i],k);
			//printf("y %d\n",y);
			if(dist[y]<=p[i])printf("%d\n",dist[x[i]]-dist[y]);
			else printf("%d\n",dist[x[i]]-p[i]);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 29144
final_rank: 4