Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // From https://www.geeksforgeeks.org/find-the-node-at-the-centre-of-an-n-ary-tree/
- // C++ implementation of
- // the above approach
- #include <bits/stdc++.h>
- using namespace std;
- // To create tree
- map<int, vector<int> > tree;
- // Function to store the path
- // from given vertex to the target
- // vertex in a vector path
- bool getDiameterPath(int vertex,
- int targetVertex,
- int parent,
- vector<int>& path)
- {
- // If the target node is found,
- // push it into path vector
- if (vertex == targetVertex) {
- path.push_back(vertex);
- return true;
- }
- for (auto i : tree[vertex]) {
- // To prevent visiting a
- // node already visited
- if (i == parent)
- continue;
- // Recursive call to the neighbours
- // of current node inorder
- // to get the path
- if (getDiameterPath(i, targetVertex,
- vertex, path)) {
- path.push_back(vertex);
- return true;
- }
- }
- return false;
- }
- // Function to obtain and return the
- // farthest node from a given vertex
- void farthestNode(int vertex, int parent,
- int height, int& maxHeight,
- int& maxHeightNode)
- {
- // If the current height is maximum
- // so far, then save the current node
- if (height > maxHeight) {
- maxHeight = height;
- maxHeightNode = vertex;
- }
- // Iterate over all the neighbours
- // of current node
- for (auto i : tree[vertex]) {
- // This is to prevent visiting
- // a already visited node
- if (i == parent)
- continue;
- // Next call will be at 1 height
- // higher than our current height
- farthestNode(i, vertex,
- height + 1,
- maxHeight,
- maxHeightNode);
- }
- }
- // Function to add edges
- void addedge(int a, int b)
- {
- tree[a].push_back(b);
- tree[b].push_back(a);
- }
- int FindCenter(int n)
- {
- // Now we will find the 1st farthest
- // node from 0(any arbitary node)
- // Perform DFS from 0 and update
- // the maxHeightNode to obtain
- // the farthest node from 0
- // Reset to -1
- int maxHeight = -1;
- // Reset to -1
- int maxHeightNode = -1;
- farthestNode(tree.begin()->first, -1, 0, maxHeight,
- maxHeightNode);
- // Stores one end of the diameter
- int leaf1 = maxHeightNode;
- // Similarly the other end of
- // the diameter
- // Reset the maxHeight
- maxHeight = -1;
- farthestNode(maxHeightNode,
- -1, 0, maxHeight,
- maxHeightNode);
- // Stores the second end
- // of the diameter
- int leaf2 = maxHeightNode;
- // Store the diameter into
- // the vector path
- vector<int> path;
- // Diameter is equal to the
- // path between the two farthest
- // nodes leaf1 and leaf2
- getDiameterPath(leaf1, leaf2,
- -1, path);
- int pathSize = path.size();
- return path[pathSize / 2];
- }
- void dfs2(int s, int xn, map<int, bool> &vis, map<int, vector<int> > &new_tree)
- {
- if (vis[s])
- return;
- vis[s] = true;
- for (auto d : tree[s]) {
- if (vis[d])
- continue;
- new_tree[s].push_back(d);
- new_tree[d].push_back(s);
- dfs2(d, xn, vis, new_tree);
- }
- }
- void dfs1(int s, int xn, map<int, bool> &vis, map<int, vector<int> > &new_tree)
- {
- if (vis[s])
- return;
- vis[s] = true;
- for (auto d : tree[s]) {
- if (vis[d])
- continue;
- if (d == xn)
- dfs2(d, xn, vis, new_tree);
- else
- dfs1(d, xn, vis, new_tree);
- }
- }
- void reduce_graph(int cn, int xn)
- {
- map<int, bool> vis;
- map<int, vector<int> > new_tree;
- dfs1(cn, xn, vis, new_tree);
- tree = new_tree;
- }
- int main()
- {
- int t = 1;
- // cin >> t;
- while (t--) {
- int n = 990;
- // cin >> n;
- tree.clear();
- // for (int i = 0; i < n - 1; i++) {
- // int u, v;
- // cin >> u >> v;
- // u--;
- // v--;
- // addedge(u, v);
- // }
- int curNode = 2, nextNode = 4, par = 1, dif = 2, flag = 0;
- while (curNode <= n) {
- addedge(curNode-1, par-1);
- // cerr << par << ' ' << curNode << '\n';
- if (flag == 0) flag = 1;
- else ++par;
- ++curNode;
- if (curNode == nextNode) {
- flag = 0;
- par = nextNode - dif;
- ++dif;
- nextNode += dif;
- }
- }
- auto answer = [&] (int u) {
- for (int v : tree[u]) {
- if (v > u) return v + 1;
- }
- return -1;
- };
- int queries = 0;
- while (tree.size() > 0) {
- int cn = FindCenter(tree.size());
- cout << "? " << cn + 1 << endl;
- cout << flush;
- ++queries;
- int response = answer(cn);
- // cin >> response;
- if (response == -1) {
- cout << "! " << cn + 1 << endl;
- cout << flush;
- break;
- }
- reduce_graph(cn, response - 1);
- if (tree.size() == 0) {
- cout << "! " << response << endl;
- cout << flush;
- break;
- }
- }
- cerr << "Used " << queries << " queries\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement