Directi Interview Question
Software EngineersTeam: Media.net
Country: India
Interview Type: Phone Interview
well thats a simple recursion code //
int maxedge(struct node *root,int c,int k)
{
if(root==NULL)
return 0;
if(c==k)
return 0;
int left edge=0;
int right edge=0;
if(root->left)
left edge=(root->left->wt);//edge to the left node
if(root->right)
right edge=(root->right->wt);//edge to the right node
int l=0,r=0;
if(root->left)
l= maxedge(root->left,c+1,k);
if(root->right)
r=maxedge(root->right,c+1,k);
return max( left edge+l,right edge+r);
}
Assuming that we are given the adjacency list of the tree which contains the link to the parent. If not, we can easily build it in linear time.
We can use dynamic programming to solve this problem (in fact, my solution will work in a general graph, not only on a tree). So, our DP state will be:
DP[i][j]: max weigth we can achieve if we are on node i with j jumps left
Now the code in C++11 (I am coding my solution directly here to train for an interview, so it may contain some bugs/typos):
int root;
int weight[MAX_N]; // weight of each node
vector <int> g[MAX_N]; // adjacency list
int dp[MAX_N][MAX_K]; // initialized with -1
int solve(int node, int jumps){
if(jumps == 0)
return weight[node];
if(dp[node][jumps] == -1){
dp[node][jumps] = weight[node];
for(int v : g[node])
dp[node][jumps] = max(dp[node][jumps], solve(v, jumps - 1));
}
return dp[node][jumps];
}
We can now analize the complexity of this solution: O((V + E) * K).
We may be able to improve this solution using bottom-up construction and some dynamic programming optimization (divide and conquer optimization I think, but I haven't study it yet).
It's not correct. I didn't read the question right and assumed that the weights were on the nodes instead of edges.
Assuming we can collect the weigth of an edge multiple times:
We can adapt the solution easily and even improve it with the following observation:
- If we reach the maximum edge, we can just use that edge on all the jumps left.
If can only collect the weigth of each edge once, then the problem gets much more difficult and we need a much clever DP or a brute force with some heuristics and optimizations.
I think this problem can be turned in to unbounded knapsack problem and we can apply that concept here.
Store each edge weights as values and how many steps it took to reach those edges as their weights. store these values and weights in arrays. Now we need to maximise the value for a given weight, assuming we're given infinite set of each of these values.
Lemme know if this is right way to solve this problem.
foreach node in the branch which is no more than K deep, get:
- JB February 06, 2015W - max weight collected one way from the root to this node (this is a sum of the parent W and the weight of the edge taken)
D - depth traversed to this node
E - an incident edge with maximum value (edge to the parent or a child)
M - maximum collectible weight if jumping back and forth along the edge E
M = W + V * (K - D)
Maximum of M is the answer.
For example for K = 5, the maximum M is in the left most leaf, M = 29 + 24 * 3 = 101. Note that the leaves are not pictured by the author..