Advertisement
erek1e

BOI '20 - Village (Maximum)

Jun 30th, 2023
938
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.23 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. vector<vector<int>> g;
  7. vector<int> subtree;
  8. void dfsSubtree(int node, int parent = 0) {
  9.     subtree[node] = 1;
  10.     for (int child : g[node]) {
  11.         if (child != parent) {
  12.             dfsSubtree(child, node);
  13.             subtree[node] += subtree[child];
  14.         }
  15.     }
  16. }
  17.  
  18. vector<vector<pair<int, int>>> components;
  19. void dfsComponent(int node, int parent = 0, int depth = 0) {
  20.     components.back().emplace_back(node, depth);
  21.     for (int child : g[node]) {
  22.         if (child != parent) dfsComponent(child, node, depth+1);
  23.     }
  24. }
  25.  
  26. int main() {
  27.     int n; cin >> n;
  28.     g.resize(1+n);
  29.     for (int i = 0; i < n-1; ++i) {
  30.         int u, v; cin >> u >> v;
  31.         g[u].push_back(v);
  32.         g[v].push_back(u);
  33.     }
  34.     subtree.resize(1+n);
  35.     dfsSubtree(1);
  36.    
  37.     // find centroid
  38.     int centroid = 1;
  39.     for (bool going = true; going; ) {
  40.         going = false;
  41.         for (int child : g[centroid]) {
  42.             if (subtree[child] > subtree[centroid]) continue; // parent
  43.             if (2*subtree[child] > n) {
  44.                 centroid = child;
  45.                 going = true;
  46.                 break;
  47.             }
  48.         }
  49.     }
  50.  
  51.     for (int child : g[centroid]) {
  52.         components.emplace_back();
  53.         dfsComponent(child, centroid, 1);
  54.     }
  55.     components.push_back({{centroid, 0}});
  56.     int m = components.size();
  57.  
  58.     vector<int> destination(1+n);
  59.     long long totalDist = 0;
  60.  
  61.     // if there are two centroids, biggest component will be towards the second centroid, and will contain half of the nodes in the graph
  62.     int c1 = 0, p1 = 0, c2 = 0, p2 = n/2;
  63.     while (p2 >= (int)components[c2].size()) p2 -= components[c2++].size();
  64.     for (int i = 0; i < n; ++i) {
  65.         auto [a, aDist] = components[c1][p1];
  66.         auto [b, bDist] = components[c2][p2];
  67.         destination[a] = b;
  68.  
  69.         totalDist += aDist + bDist;
  70.  
  71.         ++p1, ++p2;
  72.         if (p1 == (int)components[c1].size()) c1 = (c1+1)%m, p1 = 0;
  73.         if (p2 == (int)components[c2].size()) c2 = (c2+1)%m, p2 = 0;
  74.     }
  75.     cout << totalDist << endl;
  76.     for (int i = 1; i <= n; ++i) cout << destination[i] << ' ';
  77.     cout << endl;
  78.     return 0;
  79. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement