Advertisement
Guest User

Untitled

a guest
Nov 17th, 2021
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.59 KB | None | 0 0
  1. // From https://www.geeksforgeeks.org/find-the-node-at-the-centre-of-an-n-ary-tree/
  2.  
  3. // C++ implementation of
  4. // the above approach
  5.  
  6. #include <bits/stdc++.h>
  7. using namespace std;
  8.  
  9. // To create tree
  10. map<int, vector<int> > tree;
  11.  
  12. // Function to store the path
  13. // from given vertex to the target
  14. // vertex in a vector path
  15. bool getDiameterPath(int vertex,
  16.                     int targetVertex,
  17.                     int parent,
  18.                     vector<int>& path)
  19. {
  20.  
  21.     // If the target node is found,
  22.     // push it into path vector
  23.     if (vertex == targetVertex) {
  24.  
  25.         path.push_back(vertex);
  26.         return true;
  27.     }
  28.  
  29.     for (auto i : tree[vertex]) {
  30.  
  31.         // To prevent visiting a
  32.         // node already visited
  33.         if (i == parent)
  34.             continue;
  35.  
  36.         // Recursive call to the neighbours
  37.         // of current node inorder
  38.         // to get the path
  39.         if (getDiameterPath(i, targetVertex,
  40.                             vertex, path)) {
  41.             path.push_back(vertex);
  42.             return true;
  43.         }
  44.     }
  45.  
  46.     return false;
  47. }
  48.  
  49. // Function to obtain and return the
  50. // farthest node from a given vertex
  51. void farthestNode(int vertex, int parent,
  52.                 int height, int& maxHeight,
  53.                 int& maxHeightNode)
  54. {
  55.  
  56.     // If the current height is maximum
  57.     // so far, then save the current node
  58.     if (height > maxHeight) {
  59.         maxHeight = height;
  60.         maxHeightNode = vertex;
  61.     }
  62.  
  63.     // Iterate over all the neighbours
  64.     // of current node
  65.     for (auto i : tree[vertex]) {
  66.         // This is to prevent visiting
  67.         // a already visited node
  68.         if (i == parent)
  69.             continue;
  70.  
  71.         // Next call will be at 1 height
  72.         // higher than our current height
  73.         farthestNode(i, vertex,
  74.                     height + 1,
  75.                     maxHeight,
  76.                     maxHeightNode);
  77.     }
  78. }
  79.  
  80. // Function to add edges
  81. void addedge(int a, int b)
  82. {
  83.     tree[a].push_back(b);
  84.     tree[b].push_back(a);
  85. }
  86.  
  87. int FindCenter(int n)
  88. {
  89.     // Now we will find the 1st farthest
  90.     // node from 0(any arbitary node)
  91.  
  92.     // Perform DFS from 0 and update
  93.     // the maxHeightNode to obtain
  94.     // the farthest node from 0
  95.  
  96.     // Reset to -1
  97.     int maxHeight = -1;
  98.  
  99.     // Reset to -1
  100.     int maxHeightNode = -1;
  101.  
  102.     farthestNode(tree.begin()->first, -1, 0, maxHeight,
  103.                 maxHeightNode);
  104.  
  105.     // Stores one end of the diameter
  106.     int leaf1 = maxHeightNode;
  107.  
  108.     // Similarly the other end of
  109.     // the diameter
  110.  
  111.     // Reset the maxHeight
  112.     maxHeight = -1;
  113.     farthestNode(maxHeightNode,
  114.                 -1, 0, maxHeight,
  115.                 maxHeightNode);
  116.  
  117.     // Stores the second end
  118.     // of the diameter
  119.     int leaf2 = maxHeightNode;
  120.  
  121.     // Store the diameter into
  122.     // the vector path
  123.     vector<int> path;
  124.  
  125.     // Diameter is equal to the
  126.     // path between the two farthest
  127.     // nodes leaf1 and leaf2
  128.     getDiameterPath(leaf1, leaf2,
  129.                     -1, path);
  130.  
  131.     int pathSize = path.size();
  132.  
  133.     return path[pathSize / 2];
  134. }
  135.  
  136. void dfs2(int s, int xn, map<int, bool> &vis, map<int, vector<int> > &new_tree)
  137. {
  138.     if (vis[s])
  139.         return;
  140.     vis[s] = true;
  141.     for (auto d : tree[s]) {
  142.         if (vis[d])
  143.             continue;
  144.         new_tree[s].push_back(d);
  145.         new_tree[d].push_back(s);
  146.         dfs2(d, xn, vis, new_tree);
  147.     }
  148. }
  149.  
  150. void dfs1(int s, int xn, map<int, bool> &vis, map<int, vector<int> > &new_tree)
  151. {
  152.     if (vis[s])
  153.         return;
  154.     vis[s] = true;
  155.     for (auto d : tree[s]) {
  156.         if (vis[d])
  157.             continue;
  158.         if (d == xn)
  159.             dfs2(d, xn, vis, new_tree);
  160.         else
  161.             dfs1(d, xn, vis, new_tree);
  162.     }
  163. }
  164.  
  165. void reduce_graph(int cn, int xn)
  166. {
  167.     map<int, bool> vis;
  168.     map<int, vector<int> > new_tree;
  169.     dfs1(cn, xn, vis, new_tree);
  170.     tree = new_tree;
  171. }
  172.  
  173. int main()
  174. {
  175.     int t = 1;
  176.     // cin >> t;
  177.     while (t--) {
  178.         int n = 990;
  179.         // cin >> n;
  180.         tree.clear();
  181.         // for (int i = 0; i < n - 1; i++) {
  182.         //     int u, v;
  183.         //     cin >> u >> v;
  184.         //     u--;
  185.         //     v--;
  186.         //     addedge(u, v);
  187.         // }
  188.         int curNode = 2, nextNode = 4, par = 1, dif = 2, flag = 0;
  189.         while (curNode <= n) {
  190.             addedge(curNode-1, par-1);
  191.             // cerr << par << ' ' << curNode << '\n';
  192.             if (flag == 0) flag = 1;
  193.             else ++par;
  194.  
  195.             ++curNode;
  196.             if (curNode == nextNode) {
  197.                 flag = 0;
  198.                 par = nextNode - dif;
  199.                 ++dif;
  200.                 nextNode += dif;
  201.             }
  202.         }
  203.        
  204.         auto answer = [&] (int u) {
  205.             for (int v : tree[u]) {
  206.                 if (v > u) return v + 1;
  207.             }
  208.             return -1;
  209.         };
  210.  
  211.         int queries = 0;
  212.         while (tree.size() > 0) {
  213.             int cn = FindCenter(tree.size());
  214.             cout << "? " << cn + 1 << endl;
  215.             cout << flush;
  216.             ++queries;
  217.             int response = answer(cn);
  218.             // cin >> response;
  219.             if (response == -1) {
  220.                 cout << "! " << cn + 1 << endl;
  221.                 cout << flush;
  222.                 break;
  223.             }
  224.             reduce_graph(cn, response - 1);
  225.             if (tree.size() == 0) {
  226.                 cout << "! " << response << endl;
  227.                 cout << flush;
  228.                 break;
  229.             }
  230.         }
  231.         cerr << "Used " << queries << " queries\n";
  232.     }
  233.  
  234.     return 0;
  235. }
  236.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement