Advertisement
mickypinata

IPST59: Speed Up

Nov 11th, 2021
884
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.51 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long lli;
  5. typedef pair<int, int> pii;
  6. typedef pair<lli, int> pli;
  7. typedef pair<int, lli> pil;
  8. typedef tuple<lli, int, int, int> tpp;
  9.  
  10. const int N = 8e4 + 5;
  11. const int L = 10 + 5;
  12. const int Q = 8 + 5;
  13.  
  14. vector<pii> adj[N];
  15. vector<pil> cAdj[L];
  16. vector<int> potion;
  17. lli dist[L][N], cDist[L][Q][L];
  18. int nVertex;
  19. bool visited[N], cVisited[L][Q][L], isInCp[N];
  20.  
  21. void Dijkstra(int i){
  22.     int st = potion[i];
  23.     priority_queue<pli, vector<pli>, greater<pli>> pq;
  24.     for(int u = 0; u <= nVertex + 1; ++u){
  25.         visited[u] = false;
  26.     }
  27.     dist[i][st] = 0;
  28.     pq.emplace(dist[i][st], st);
  29.     while(!pq.empty()){
  30.         int u = pq.top().second;
  31.         pq.pop();
  32.         if(visited[u]){
  33.             continue;
  34.         }
  35.         if(isInCp[u]){
  36.             int idx = lower_bound(potion.begin(), potion.end(), u) - potion.begin();
  37.             if(i != idx){
  38.                 cAdj[i].emplace_back(idx, dist[i][u]);
  39.             }
  40.         }
  41.         visited[u] = true;
  42.         for(pii nxt : adj[u]){
  43.             int v = nxt.first;
  44.             int w = nxt.second;
  45.             if(!visited[v] && dist[i][u] + w < dist[i][v]){
  46.                 dist[i][v] = dist[i][u] + w;
  47.                 pq.emplace(dist[i][v], v);
  48.             }
  49.         }
  50.     }
  51. }
  52.  
  53. int main(){
  54.  
  55.     int nEdge, nPotionRoom, limPotion;
  56.     scanf("%d%d%d%d", &nVertex, &nEdge, &nPotionRoom, &limPotion);
  57.     for(int i = 1; i <= nEdge; ++i){
  58.         int u, v, w;
  59.         scanf("%d%d%d", &u, &v, &w);
  60.         adj[u].emplace_back(v, w);
  61.     }
  62.     adj[0].emplace_back(1, 0);
  63.     adj[nVertex].emplace_back(nVertex + 1, 0);
  64.  
  65.     potion.push_back(0);
  66.     potion.push_back(nVertex + 1);
  67.     for(int i = 1; i <= nPotionRoom; ++i){
  68.         int u;
  69.         scanf("%d", &u);
  70.         potion.push_back(u);
  71.         isInCp[u] = true;
  72.     }
  73.     isInCp[nVertex + 1] = true;
  74.     sort(potion.begin(), potion.end());
  75.  
  76.     for(int i = 0; i <= nPotionRoom; ++i){
  77.         for(int u = 0; u <= nVertex + 1; ++u){
  78.             dist[i][u] = 1e18;
  79.         }
  80.     }
  81.     for(int i = 0; i <= nPotionRoom; ++i){
  82.         Dijkstra(i);
  83.     }
  84.  
  85.     for(int u = 0; u <= nPotionRoom + 1; ++u){
  86.         for(int ptn = 0; ptn <= limPotion; ++ptn){
  87.             for(int lst = 0; lst <= nPotionRoom + 1; ++lst){
  88.                 cDist[u][ptn][lst] = 1e18;
  89.             }
  90.         }
  91.     }
  92.     priority_queue<tpp, vector<tpp>, greater<tpp>> pq;
  93.     cDist[0][0][0] = 0;
  94.     pq.emplace(cDist[0][0][0], 0, 0, 0);
  95.     while(!pq.empty()){
  96.         int u = get<1>(pq.top());
  97.         int ptn = get<2>(pq.top());
  98.         int lst = get<3>(pq.top());
  99.         pq.pop();
  100.         if(cVisited[u][ptn][lst]){
  101.             continue;
  102.         }
  103.         if(u == nPotionRoom + 1){
  104.             cout << cDist[u][ptn][lst];
  105.             return 0;
  106.         }
  107.         cVisited[u][ptn][lst] = true;
  108.         if(u != lst && ptn < limPotion){
  109.             if(!cVisited[u][ptn + 1][u] && cDist[u][ptn][lst] < cDist[u][ptn + 1][u]){
  110.                 cDist[u][ptn + 1][u] = cDist[u][ptn][lst];
  111.                 pq.emplace(cDist[u][ptn + 1][u], u, ptn + 1, u);
  112.             }
  113.         }
  114.         for(pil nxt : cAdj[u]){
  115.             int v = nxt.first;
  116.             lli w = nxt.second;
  117.             if(!cVisited[v][ptn][lst] && cDist[u][ptn][lst] + (w >> ptn) < cDist[v][ptn][lst]){
  118.                 cDist[v][ptn][lst] = cDist[u][ptn][lst] + (w >> ptn);
  119.                 pq.emplace(cDist[v][ptn][lst], v, ptn, lst);
  120.             }
  121.         }
  122.     }
  123.  
  124.     return 0;
  125. }
  126.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement