Submission #1065719

#TimeUsernameProblemLanguageResultExecution timeMemory
1065719alexddTrain (APIO24_train)C++17
0 / 100
1097 ms20928 KiB
#include "train.h" #include <bits/stdc++.h> using namespace std; const long long LIM = 0; const long long INF = 1e14; struct train { int from,to; int tin,tout; int cost; }; bool cmp_trains(train x, train y) { return x.tin < y.tin; } bool cmp_meals(pair<int,int> x, pair<int,int> y) { return x.second < y.second; } vector<train> trains; vector<pair<int,int>> meals; long long dp[100005]; vector<int> meal_cost; vector<int> train_ends[100005]; bool isbig[100005]; int cntin[100005],cntout[100005]; vector<int> big_nodes; long long prec[100005]; long long calced[100005],inplus[100005]; int poz_meals=-1; void solve_small(int i) { for(int j:train_ends[trains[i].from]) { if(trains[j].tout <= trains[i].tin) { long long cnt=0; for(int k=0;k<=poz_meals;k++) if(meals[k].first > trains[j].tout) cnt++; if(dp[j] < dp[i]) dp[i] = min(dp[i], dp[j] + cnt*meal_cost[trains[i].from] + trains[i].cost); } } } void solve_big(int i) { for(int j:train_ends[trains[i].from]) { if(trains[j].tout <= trains[i].tin) { long long cnt=0; for(int k=0;k<=poz_meals;k++) if(meals[k].first > trains[j].tout) cnt++; if(dp[j] < dp[i]) dp[i] = min(dp[i], dp[j] + cnt*meal_cost[trains[i].from] + trains[i].cost); } } assert(isbig[trains[i].from]); dp[i] = min(dp[i], prec[trains[i].from] + trains[i].cost); } void baga_big(int id) { for(int x:big_nodes) { prec[x]=INF; for(int y:train_ends[x]) { if(meals[id].first > trains[y].tout) { inplus[y] = min(INF, inplus[y] + meal_cost[x]); calced[y] = min(INF, calced[y] + meal_cost[x]); } prec[x] = min(prec[x], calced[y]); } } } void update_big(int i, int W) { while(poz_meals+1 < W && meals[poz_meals+1].second < trains[i].tin) { poz_meals++; baga_big(poz_meals); } } long long solve(int N, int M, int W, std::vector<int> T, std::vector<int> X, std::vector<int> Y, std::vector<int> A, std::vector<int> B, std::vector<int> C, std::vector<int> L, std::vector<int> R) { meal_cost = T; for(int i=0;i<M;i++) { trains.push_back({X[i],Y[i],A[i],B[i],C[i]}); cntin[trains[i].to]++; cntout[trains[i].from]++; calced[i]=INF; } for(int i=0;i<W;i++) { meals.push_back({L[i],R[i]}); } sort(trains.begin(),trains.end(),cmp_trains); sort(meals.begin(),meals.end(),cmp_meals); for(int i=0;i<M;i++) train_ends[trains[i].to].push_back(i); for(int i=0;i<N;i++) { if(cntin[i]+cntout[i] > LIM) { isbig[i]=1; big_nodes.push_back(i); prec[i]=INF; } } for(int i=0;i<M;i++) { update_big(i,W); dp[i]=INF; if(trains[i].from==0) { long long cnt=0; for(auto [x,y]:meals) if(y < trains[i].tin) cnt++; dp[i] = min(dp[i], cnt*meal_cost[trains[i].from] + trains[i].cost); } if(isbig[trains[i].from]) solve_big(i); else solve_small(i); calced[i] = dp[i]+inplus[i]; if(isbig[trains[i].to]) { prec[trains[i].to] = min(prec[trains[i].to], calced[i]); } } long long rez=INF; for(int i=0;i<M;i++) { if(trains[i].to==N-1) { long long cnt=0; for(auto [x,y]:meals) if(x > trains[i].tout) cnt++; rez = min(rez, dp[i] + cnt*meal_cost[N-1]); } } if(rez==INF) return -1; else return rez; } /** dp[i] = costul minim de a parcurge o ruta care incepe la nodul 0, a.i. ultimul tren luat sa fie i (cumparam un meal doar daca e obligatoriu) */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...