Advertisement
Guest User

Untitled

a guest
Nov 16th, 2019
1,735
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.91 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <queue>
  5. using namespace std;
  6.  
  7. using llg = long long;
  8.  
  9. const int maxNod = (int)(1e5) + 5;
  10. const int maxEdges = 3*(int)(1e5) + 5;
  11. const int maxQueries = 3*(int)(1e5) + 5;
  12.  
  13. const int maxTokens = 2*maxQueries;
  14.  
  15. const llg BIG = (llg)(1e9) * (llg)(1e9);
  16.  
  17. int nbNod, nbEdges, nbCentrals, nbQueries;
  18. llg rep[maxQueries];
  19.  
  20. // DSU
  21.  
  22. int dsuRepr[maxNod];
  23. int dsuSize[maxNod];
  24. vector<int> tokenIn[maxNod];
  25.  
  26. int baseTok[maxTokens];
  27.  
  28. void dsuInit()
  29. {
  30.     for (int nod = 0; nod < maxNod; ++nod) {
  31.         dsuRepr[nod] = nod;
  32.         dsuSize[nod] = 1;
  33.     }
  34. }
  35.  
  36. int dsuFind(int x)
  37. {
  38.     if (x != dsuRepr[x]) {
  39.         dsuRepr[x] = dsuFind(dsuRepr[x]);
  40.     }
  41.     return dsuRepr[x];
  42. }
  43.  
  44. void dsuMerge(int small, int big, llg curCap)
  45. {
  46.     small = dsuFind(small);
  47.     big = dsuFind(big);
  48.     if (small == big) return;
  49.     if (dsuSize[small] > dsuSize[big]) swap(small, big);
  50.  
  51.     for (int token : tokenIn[small]) {
  52.         int oth = token^1;
  53.         int query = token/2;
  54.         if (dsuFind(baseTok[oth]) == big) {
  55.             rep[query] = curCap;
  56.         }
  57.         tokenIn[big].push_back(token);
  58.     }
  59.  
  60.     tokenIn[small].clear();
  61.     tokenIn[small].shrink_to_fit();
  62.  
  63.     dsuSize[big] += dsuSize[small];
  64.     dsuRepr[small] = big;
  65. }
  66.  
  67. // Dijkstra
  68.  
  69. vector<pair<int, llg>> adj[maxNod];
  70. llg mdis[maxNod];
  71.  
  72. void dijkstra()
  73. {
  74.     priority_queue<pair<llg, int>> pq;
  75.     for (int nod = 0; nod < nbNod; ++nod) {
  76.         if (nod < nbCentrals) {
  77.             pq.push({0, nod});
  78.         } else {
  79.             mdis[nod] = BIG;
  80.         }
  81.     }
  82.  
  83.     while (! pq.empty()) {
  84.         llg dist = -pq.top().first;
  85.         int nod = pq.top().second;
  86.         pq.pop();
  87.         if (dist != mdis[nod]) continue;
  88.  
  89.         for (auto rawNeigh : adj[nod]) {
  90.             int neighbor = rawNeigh.first;
  91.             llg newDis = dist + rawNeigh.second;
  92.             if (newDis < mdis[neighbor]) {
  93.                 mdis[neighbor] = newDis;
  94.                 pq.push({-newDis, neighbor});
  95.             }
  96.         }
  97.     }
  98. }
  99.  
  100. // Main
  101.  
  102. struct Edge
  103. {
  104.     llg weight, n1, n2;
  105. };
  106.  
  107. bool operator<(Edge a, Edge b)
  108. {
  109.     return a.weight < b.weight;
  110. }
  111.  
  112. vector<Edge> tabEdges;
  113.  
  114. int main()
  115. {
  116.     ios::sync_with_stdio(false);
  117.     cin.tie(0);
  118.     dsuInit();
  119.  
  120.     cin >> nbNod >> nbEdges >> nbCentrals >> nbQueries;
  121.     for (int iEdge = 0; iEdge < nbEdges; ++iEdge) {
  122.         int n1, n2; llg weight;
  123.         cin >> n1 >> n2 >> weight;
  124.         --n1; --n2;
  125.         adj[n1].emplace_back(n2, weight);
  126.         adj[n2].emplace_back(n1, weight);
  127.         tabEdges.push_back({weight, n1, n2});
  128.     }
  129.  
  130.     for (int query = 0; query < nbQueries; ++query) {
  131.         int n1, n2;
  132.         cin >> n1 >> n2;
  133.         --n1; --n2;
  134.         int tk1 = 2*query, tk2 = 2*query+1;
  135.  
  136.         baseTok[tk1] = n1;
  137.         baseTok[tk2] = n2;
  138.  
  139.         tokenIn[n1].push_back(tk1);
  140.         tokenIn[n2].push_back(tk2);
  141.     }
  142.  
  143.     dijkstra();
  144.  
  145.     for (auto &edge : tabEdges) {
  146.         edge.weight += mdis[edge.n1] + mdis[edge.n2];
  147.     }
  148.  
  149.     sort(tabEdges.begin(), tabEdges.end());
  150.  
  151.     for (auto edge : tabEdges) {
  152.         dsuMerge(edge.n1, edge.n2, edge.weight);
  153.     }
  154.  
  155.     for (int query = 0; query < nbQueries; ++query) {
  156.         cout << rep[query] << "\n";
  157.     }
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement