Блог пользователя egor.okhterov

Автор egor.okhterov, история, 9 лет назад, По-английски

We have a tree with n (2 ≤ n ≤ 1000) nodes and we need to find k (1 ≤ k ≤ 100 and k ≤ n - 1) vertices such that the path going through all of these vertices has the maximum length.

Note:

  • The path should start at vertex 1 and finish also at vertex 1.
  • The algorithm has to return just the length of the maximum path (the path itself is not needed).
  • The weight for an edge has following restrictions: 0 ≤ w ≤ 100000.

Let's say we have the following tree with n = 5 vertices:

We need to find k = 3 vertices which will give us the longest path.

For this tree the maximal path is the following:
15241

It has the total length of 13 + 18 + 10 + 5 = 46.
So, for that particular tree we have to print 46 as our result.


I came up with a following greedy/dp-like solution. First we solve the problem for k = 1 and we remember this solution in a linked list 1v1. After that we try to solve the problem for k = 2 by trying all of the remaining n - 2 vertices and insert it in the current path: 1uv1 and 1vu1. After going through all of the vertices we choose the one which gave us the best result. Then we proceed to solve k = 3.

The problem is that it looks like this solution is not correct, because it fails the tests for this problem. I cannot prove that my solution is correct and I cannot disprove it. All I managed to do is to generate millions of different random trees and in all of these cases my clever solution matched bruteforce solution.

For now all my effort is directed towards generating a counter example in which my method will fail, but if it is correct I'd be glad to see the reasoning why is it correct.

  • Проголосовать: нравится
  • +17
  • Проголосовать: не нравится

»
9 лет назад, скрыть # |
Rev. 3  
Проголосовать: нравится 0 Проголосовать: не нравится

Are all the k vertices required to be distinct?

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +14 Проголосовать: не нравится

solution forgetting about K below :((

wrong
»
9 лет назад, скрыть # |
 
Проголосовать: нравится -18 Проголосовать: не нравится

Here is a solution:

First, consider the problem where we do not need to return to the first vertex at the end. Then, one can notice that the optimal solution is to, at each step, visit an arbitrary farthest vertex from the current vertex (and mark the current vertex as visited).

The complexity of the solution to this problem is O(N * K)

However, now we can iterate over all possible ending vertices and perform the same algorithm. Total complexity would be O(N^2 * K).

»
9 лет назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Since for each node of the route we only care about the next node(I will call it matching a node with another one), now we can do this:
Dp[v][i][false,true]=the maximum lenght of a route in v's subtree such that we have i not matched nodes yet and true=the second node of the route is in this subtree/false=otherwise.
O(n*k^2)

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

managed to get a very large input where your solution fails (it's smaller than answer shown in udebug) https://puu.sh/uEbNc/f1d8e8f44c.in

»
9 лет назад, скрыть # |
 
Проголосовать: нравится +16 Проголосовать: не нравится

All I managed to do is to generate millions of different random trees and in all of these cases my clever solution matched bruteforce solution.

You likely made some mistake in the generator/script. I have run your solution on hundreds of small tests and it was enough.

1
6 3
1 2
2 2
3 2
3 1
4 3

Your solution finds a path 1-5-2-6-1 with total length 24. The optimal path is 1-6-2-4-1 with total length 26.

(drawn with CS-Academy tool)

  • »
    »
    9 лет назад, скрыть # ^ |
    Rev. 2  
    Проголосовать: нравится 0 Проголосовать: не нравится

    You likely made some mistake in the generator/script. I have run your solution on hundreds of small tests and it was enough.

    It looks like I had a bad generator.

    Now, looking at this tree it doesn't seem to me that my algorithm can be cured, though I'll try to think about it a little bit more.


    Well, what I notice is that this optimal path 1-6-2-4-1 can be built by looking for the furthest vertex from the current one. Again, I'm not sure that this will work in general =)

»
9 лет назад, скрыть # |
Rev. 2  
Проголосовать: нравится +31 Проголосовать: не нравится

root your tree in node 1

let us say there is an edge between node u and node v , if you choose to visit [ x ] nodes in the subtree of v then there is x nodes there and K — x nodes outside

then you will traverse the edge min(x , K — x) * 2 times if you behave optimally and you can proof that you can always do that

it turned out to be a normal knapsack on a tree

dp[node][visited nodes in its subtree]

call dp[1][K-1]