Guest User

Untitled

a guest
Nov 16th, 2019
1,557
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.03 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <queue>
  5.  
  6.  
  7. struct Edge
  8. {
  9.     Edge(int u, int v, long long w) : start(u), end(v), weight(w) {}
  10.     int start, end;
  11.     long long weight;
  12.  
  13.     bool operator <(const Edge &other) const
  14.     {
  15.         return (other.weight < weight);
  16.     }
  17. };
  18.  
  19. const int MAXN = 2e5;
  20. const int LOGN = 18;
  21.  
  22. std::vector<Edge> graph[MAXN];
  23. std::priority_queue<Edge> dijkstra;
  24.  
  25. int closestSpecial[MAXN];
  26. long long distToClosest[MAXN];
  27.  
  28. std::vector<Edge> paths;
  29. int component[MAXN];
  30. std::vector<Edge> specTree[MAXN];
  31.  
  32. int depth[MAXN];
  33. int ancester[MAXN][LOGN];
  34. long long weightToAnc[MAXN][LOGN];
  35.  
  36.  
  37. void computeinfluence()
  38. {
  39.     while (!dijkstra.empty())
  40.     {
  41.         int special = dijkstra.top().start;
  42.         int node = dijkstra.top().end;
  43.         long long dist = dijkstra.top().weight;
  44.         dijkstra.pop();
  45.  
  46.         if (closestSpecial[node] != -1)
  47.             continue;
  48.         closestSpecial[node] = special;
  49.         distToClosest[node] = dist;
  50.  
  51.         for (Edge &edge : graph[node])
  52.             dijkstra.emplace(special, edge.end, dist + edge.weight);
  53.     }
  54. }
  55.  
  56. int find(int node)
  57. {
  58.     if (node != component[node])
  59.         component[node] = find(component[node]);
  60.     return component[node];
  61. }
  62.  
  63. void merge(Edge &edge)
  64. {
  65.     if (find(edge.start) != find(edge.end))
  66.     {
  67.         component[find(edge.end)] = find(edge.start);
  68.         specTree[edge.start].emplace_back(edge.start, edge.end, edge.weight);
  69.         specTree[edge.end].emplace_back(edge.end, edge.start, edge.weight);
  70.     }
  71. }
  72.  
  73. void root(int node)
  74. {
  75.     for (Edge &edge : specTree[node])
  76.         if (edge.end != ancester[node][0])
  77.         {
  78.             ancester[edge.end][0] = node;
  79.             weightToAnc[edge.end][0] = edge.weight;
  80.             depth[edge.end] = depth[node] + 1;
  81.             root(edge.end);
  82.         }
  83. }
  84.  
  85. int getanc(int node, int exp)
  86. {
  87.     if (ancester[node][exp] == -1)
  88.         ancester[node][exp] = getanc(getanc(node, exp - 1), exp - 1);
  89.     return ancester[node][exp];
  90. }
  91.  
  92. long long getweighttoanc(int node, int exp)
  93. {
  94.     if (weightToAnc[node][exp] == 0)
  95.         weightToAnc[node][exp] = std::max(getweighttoanc(node, exp - 1), getweighttoanc(getanc(node, exp - 1), exp - 1));
  96.     return weightToAnc[node][exp];
  97. }
  98.  
  99. int lift(int node, int dist)
  100. {
  101.     if (dist == 0)
  102.         return node;
  103.     int exp = 31 - __builtin_clz(dist);
  104.     return lift(getanc(node, exp), dist - (1 << exp));
  105. }
  106.  
  107. long long liftw(int node, int dist)
  108. {
  109.     if (dist == 0)
  110.         return 0;
  111.     int exp = 31 - __builtin_clz(dist);
  112.     return std::max(liftw(getanc(node, exp), dist - (1 << exp)), getweighttoanc(node, exp));
  113. }
  114.  
  115. int lca(int u, int v)
  116. {
  117.     if (depth[u] < depth[v])
  118.         std::swap(u, v);
  119.     u = lift(u, depth[u] - depth[v]);
  120.  
  121.     if (u == v)
  122.         return u;
  123.     for (int iExp = 31 - __builtin_clz(depth[u]); iExp > -1; iExp--)
  124.         if (getanc(u, iExp) != getanc(v, iExp))
  125.         {
  126.             u = getanc(u, iExp);
  127.             v = getanc(v, iExp);
  128.         }
  129.  
  130.     return getanc(u, 0);
  131. }
  132.  
  133. int main()
  134. {
  135.     std::ios::sync_with_stdio(false);
  136.     std::cout.tie(nullptr);
  137.     std::cin.tie(nullptr);
  138.  
  139.     int nodes, edges, special, queries;
  140.     std::cin >> nodes >> edges >> special >> queries;
  141.    
  142.     for (int iEdge = 0; iEdge < edges; iEdge++)
  143.     {
  144.         int u, v, w;
  145.         std::cin >> u >> v >> w;
  146.         u--; v--;
  147.  
  148.         graph[u].emplace_back(u, v, w);
  149.         graph[v].emplace_back(v, u, w);
  150.     }
  151.  
  152.     for (int iSpec = 0; iSpec < special; iSpec++)
  153.         dijkstra.emplace(iSpec, iSpec, 0);
  154.     for (int iNode = 0; iNode < nodes; iNode++)
  155.         closestSpecial[iNode] = -1;
  156.     computeinfluence();
  157.  
  158.     for (int iNode = 0; iNode < nodes; iNode++)
  159.     {
  160.         component[iNode] = iNode;
  161.         for (Edge &edge : graph[iNode])
  162.             if (closestSpecial[iNode] != closestSpecial[edge.end])
  163.                 paths.emplace_back(closestSpecial[iNode], closestSpecial[edge.end], distToClosest[iNode] + edge.weight + distToClosest[edge.end]);
  164.     }
  165.  
  166.     std::sort(paths.rbegin(), paths.rend());
  167.     for (Edge &path : paths)
  168.         merge(path);
  169.  
  170.     std::fill_n((int *)ancester, special * LOGN, -1);
  171.     root(0);
  172.  
  173.     for (int iQuery = 0; iQuery < queries; iQuery++)
  174.     {
  175.         int u, v;
  176.         std::cin >> u >> v;
  177.         u--; v--;
  178.  
  179.         int w = lca(u, v);
  180.         std::cout << std::max(liftw(u, depth[u] - depth[w]), liftw(v, depth[v] - depth[w])) << ' ';
  181.     }
  182.  
  183.     std::cout << '\n';
  184.  
  185.     return 0;
  186. }
Advertisement
Add Comment
Please, Sign In to add comment