Codility problems (34) fluorum 2014

Source: Internet
Author: User
I haven't written the codility question for a long time, so I have no time, and I am not very good at analyzing some questions. This question is interesting, and I have not provided a very strict proof.


Given a tree (undirected acyclic graph), start from a node and select as many nodes as possible from the start point to the destination node path, until all nodes are traversed. If there are as many nodes in the path from the start point to the two destination nodes, select a node with a smaller label as the destination node. Continue until all nodes are traversed. Which target nodes are selected in order?

For example, from 2, select 0 for the first time, and then 1 and 0 are changed to the experienced node.

Start from 0, select 6 for the second time, and then change 4 to the node that has been experienced.

Then, start from 6, select 3 for the third time, and then change 3 to the experienced node.

Then, start from 3 and select 5 for the last time, and then change 5 to the experienced node.

Output [2, 0, 6, 3, 5]

The function header is vector <int> solution (int K, vector <int> & T );

K indicates the start number, and (I, T [I]) indicates an edge of the tree.

Variable range node count N, [1 .. 90,000], telement range [0 .. N-1]

Time complexity O (N) and space complexity O (n) are required ).

Analysis: I don't think I can solve this problem perfectly because I didn't provide a strict proof. First, the target node must be a leaf, which is more effective intuitively with deeper depth. So I sorted the leaves by leaf depth from large to small. If the depth is the same, I put the leaves with a small number in front. Define the weight value for the leaves in this order. This value is the number of new nodes on the last access path (this requires strict proof ). The weight value is defined as follows, and continues to walk to the father along the leaves until the first marked node stops. The number of nodes in this path is used as the weight of the leaf. In addition, the nodes in this path are not marked. The key issue is that the weights of each leaf should be calculated according to the previous order (because the order affects the weights of the leaves ). The intuitive feeling is that if the two leaves are on one forks, it is obvious that the deep nodes are accessed first. If they are not on the same forks, there is no loss. Finally, sorting the leaves again based on this weight is the desired result. In order to satisfy the time complexity, I used base sorting and wrote a help function to complete sorting.

The general idea is:

(1) first DFS, get the depth of each leaf and the father of each node

(2) Base sorting of all leaves by Depth

(3) Calculate the weight of each leaf in an ordered Order (complexity is equivalent to traversing the tree because it is traversed up the leaf)

(4) sort the base number of the leaves based on the calculated weights to obtain the final result.

Final code:

// you can also use includes, for example:// #include <algorithm>void help(int n, vector<pair<int,int> > &v) {  // (id, weight)     vector<vector<int> > have;    have.resize(n);    for (int i = 0; i < v.size(); ++i) {        have[v[i].first].push_back(v[i].second);    }    v.clear();    for (int i = 0; i < n; ++i) {        for (int j = 0; j < have[i].size(); ++j) {            v.push_back(make_pair(i, have[i][j]));        }    }    have.clear();    have.resize(n);    for (int i = 0; i < v.size(); ++i) {        have[v[i].second].push_back(v[i].first);    }    v.clear();    for (int i = n - 1; i >= 0; --i) {        for (int j = 0; j < have[i].size(); ++j) {            v.push_back(make_pair(have[i][j] , i));        }                }}void dfs(int x,int p,int d,vector<int> &depth, vector<int> &parent,vector<vector<int> > & con) {    parent[x] = p;    depth[x] = d;    for (int i = 0; i < con[x].size(); ++i) {        if (con[x][i] != p) {            dfs(con[x][i], x, d + 1, depth, parent, con);        }            }    }vector<int> solution(int K, vector<int> &T) {    // write your code in C++98    vector<vector<int> > con;    int n = T.size();    con.resize(n);    for (int i = 0; i < n; ++i) {        if (T[i] != i) {            con[i].push_back(T[i]);            con[T[i]].push_back(i);        }    }    vector<int> parent, depth;    depth.resize(n);    parent.resize(n);    dfs(K, -1, 0, depth, parent, con);    vector<pair<int,int> > v;    for (int i = 0; i < n; ++i) {        if ((i != K)  && (con[i].size() == 1)) {  //leaf            v.push_back(make_pair(i, depth[i]));        }    }    help(n,v);    vector<bool> mark;    mark.resize(n, false);    for (int i = 0; i < v.size(); ++i) {        int x = -1;        for (int j = v[i].first; (j >= 0) && (!mark[j]); ++x, j = parent[j]) {            mark[j] = true;        }        v[i].second = x;    }    help(n,v);     vector<int> result;    result.push_back(K);    for (int i = 0; i < v.size(); ++i) {        result.push_back(v[i].first);    }    return result;}






Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.