Submission #882046

#TimeUsernameProblemLanguageResultExecution timeMemory
882046KarootToll (BOI17_toll)C++17
100 / 100
171 ms56884 KiB
#include <iostream> #include <cmath> #include <unordered_map> #include <map> #include <set> #include <queue> #include <vector> #include <string> #include <iomanip> #include <algorithm> #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() using namespace std; typedef long long ll; ll linf = 1e15+1; inline void scoobydoobydoo(){ ios::sync_with_stdio(false); ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); } const int MAXN = 5e4+7; ll shortestPath[MAXN][20][6]; //node, binaryjump, what nodi? 0 if not possible vector<pair<ll, ll>> adj[MAXN]; ll bestAt[MAXN]; ll k, n, m, q; void initShortest(){ for (int i = 0; i < MAXN; i++){ for (auto& e : adj[i]){ int node = e.first%k; int w = e.second; shortestPath[i][0][node] = w; } } for (int j = 1; j < 20; j++){ for (int i = 0; i < n; i++){ for (int target = 0; target < k; target++){ ll best = 200000000000; for (int l = 0; l < k; l++){ if (shortestPath[i][j-1][l] != 0 && shortestPath[(i/k+(1<<(j-1)))*k+l][j-1][target] != 0){ best = min(best, shortestPath[(i/k+(1<<(j-1)))*k+l][j-1][target]+shortestPath[i][j-1][l]); } } shortestPath[i][j][target] = (best < 10000000000 ? best : 0); } } } } vector<ll> needClear; ll findBest(int node, int jumpDist, int target){ //cout << node << " " << jumpDist << " " << target << endl; if (jumpDist == 0)return 100000000000*(node != target); //cout << "here "; if (bestAt[node] != 0)return bestAt[node]; needClear.push_back(node); //cout << "there" << endl; for (int i = 18; i >= 0; i--){ if (jumpDist&(1<<i)){ //cout << i << endl; ll best = 1000000000000; for (int j = 0; j < k; j++){ if (shortestPath[node][i][j]){ best = min(best, findBest((((node/k)+(1<<i))*k)+j, jumpDist^(1<<i), target)+shortestPath[node][i][j]); } } //cout << best << " " << node << endl; return bestAt[node] = best; } } return bestAt[node] = 1000000000000; } int main(){ scoobydoobydoo(); //freopen("toll.in", "r", stdin); //freopen("toll.out", "w", stdout); cin >> k >> n >> m >> q; for (int i = 0; i < m; i++){ int a, b, t; cin >> a >> b >> t; adj[a].push_back({b, t}); } initShortest(); vector<ll> ans; while (q--){ int a, b; cin >> a >> b; int depthA = a/k; int depthB = b/k; if (a == b){ ans.push_back(0); continue; } if (depthA >= depthB){ ans.push_back(-1); continue; } int depthDiff = depthB-depthA; /*for (int i = 0; i < n; i++){ cout << bestAt[i] << " "; } cout << endl;*/ ll ret = findBest(a, depthDiff, b); ans.push_back((ret < 10000000000 ? ret : -1)); for (ll x : needClear){ bestAt[x] = 0; } needClear.clear(); } /*for (int i = 0; i < n; i++){ cout << i << "___: " << endl; for (int j = 0; j < 4; j++){ cout << j << ": "; for (int l = 0; l < k; l++){ cout << shortestPath[i][j][l] << " "; } cout << endl; } -1 3324 7419 7419 6681 }*/ for (auto& e : ans){ cout << e << endl; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...