Advertisement
mickypinata

IPST59: Delivery

Nov 13th, 2021
806
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.70 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef pair<int, int> pii;
  5.  
  6. const int L = 10 + 5;
  7. const int logN = 16;
  8.  
  9. map<int, int> tmpL, tmpR;
  10. vector<pii> linkage, sideL, sideR;
  11. int ex, rnk[1 << logN], idx[L], mat[L][L], LCAdist[2][L];
  12.  
  13. int LCAsideL(int u, int v){
  14.     int sum = 0;
  15.     if(rnk[u] < rnk[v]){
  16.         swap(u, v);
  17.     }
  18.     for(int e = ex - 1; e >= 0; --e){
  19.         if(rnk[u >> e] >= rnk[v]){
  20.             u = u >> e;
  21.             sum += e;
  22.         }
  23.     }
  24.     if(u == v){
  25.         return sum;
  26.     }
  27.     for(int e = ex - 1; e >= 0; --e){
  28.         if((u >> e) != (v >> e)){
  29.             u = u >> e;
  30.             v = v >> e;
  31.             sum += e + e;
  32.         }
  33.     }
  34.     sum += 2;
  35.     return sum;
  36. }
  37. int LCAsideR(int u, int v){
  38.     return LCAsideL(u - (1 << ex), v - (1 << ex));
  39. }
  40.  
  41. bool isL(int u){
  42.     return u < (1 << ex);
  43. }
  44.  
  45. int dist(int u, int v){
  46.     if(isL(u) && isL(v)){
  47.         return LCAsideL(u, v);
  48.     } else if(!isL(u) && !isL(v)){
  49.         return LCAsideR(u, v);
  50.     }
  51.     return 1e9;
  52. }
  53.  
  54. int main(){
  55.  
  56.     int nLink, Q;
  57.     scanf("%d%d%d", &ex, &nLink, &Q);
  58.  
  59.     rnk[0] = -1;
  60.     for(int e = 0; e < ex; ++e){
  61.         for(int i = (1 << e); i < (1 << (e + 1)); ++i){
  62.             rnk[i] = e;
  63.         }
  64.     }
  65.  
  66.     int cNodeCnt = 0;
  67.     for(int i = 1; i <= nLink; ++i){
  68.         int u, v;
  69.         scanf("%d%d", &u, &v);
  70.         if(u > v){
  71.             swap(u, v);
  72.         }
  73.         linkage.emplace_back(u, v);
  74.         if(tmpL.find(u) == tmpL.end()){
  75.             tmpL[u] = ++cNodeCnt;
  76.             idx[cNodeCnt] = u;
  77.         }
  78.         if(tmpR.find(v) == tmpR.end()){
  79.             tmpR[v] = ++cNodeCnt;
  80.             idx[cNodeCnt] = v;
  81.         }
  82.     }
  83.     for(int u = 1; u <= cNodeCnt; ++u){
  84.         for(int v = 1; v <= cNodeCnt; ++v){
  85.             if(u == v){
  86.                 mat[u][v] = 0;
  87.             } else {
  88.                 mat[u][v] = 1e9;
  89.             }
  90.         }
  91.     }
  92.     for(pii p : tmpL){
  93.         sideL.push_back(p);
  94.     }
  95.     for(int i = 0; i < (int)sideL.size() - 1; ++i){
  96.         for(int j = i + 1; j < sideL.size(); ++j){
  97.             int u = sideL[i].second;
  98.             int v = sideL[j].second;
  99.             int w = LCAsideL(sideL[i].first, sideL[j].first);
  100.             mat[u][v] = w;
  101.             mat[v][u] = w;
  102.         }
  103.     }
  104.     for(pii p : tmpR){
  105.         sideR.push_back(p);
  106.     }
  107.     for(int i = 0; i < (int)sideR.size() - 1; ++i){
  108.         for(int j = i + 1; j < sideR.size(); ++j){
  109.             int u = sideR[i].second;
  110.             int v = sideR[j].second;
  111.             int w = LCAsideR(sideR[i].first, sideR[j].first);
  112.             mat[u][v] = w;
  113.             mat[v][u] = w;
  114.         }
  115.     }
  116.     for(pii p : linkage){
  117.         int u = p.first;
  118.         int v = p.second;
  119.         u = tmpL[u];
  120.         v = tmpR[v];
  121.         mat[u][v] = 1;
  122.         mat[v][u] = 1;
  123.     }
  124.  
  125.     for(int k = 1; k <= cNodeCnt; ++k){
  126.         for(int u = 1; u <= cNodeCnt; ++u){
  127.             for(int v = 1; v <= cNodeCnt; ++v){
  128.                 if(mat[u][k] + mat[k][v] < mat[u][v]){
  129.                     mat[u][v] = mat[u][k] + mat[k][v];
  130.                 }
  131.             }
  132.         }
  133.     }
  134.  
  135.     while(Q--){
  136.         int u, v;
  137.         scanf("%d%d", &u, &v);
  138.         int mn = dist(u, v);
  139.         for(int i = 1; i <= cNodeCnt; ++i){
  140.             LCAdist[0][i] = dist(u, idx[i]);
  141.             LCAdist[1][i] = dist(v, idx[i]);
  142.         }
  143.         for(int i = 1; i <= cNodeCnt; ++i){
  144.             for(int j = 1; j <= cNodeCnt; ++j){
  145.                 if(i == j){
  146.                     continue;
  147.                 }
  148.                 mn = min(mn, LCAdist[0][i] + mat[i][j] + LCAdist[1][j]);
  149.             }
  150.         }
  151.         cout << mn << '\n';
  152.     }
  153.  
  154.     return 0;
  155. }
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement