lvisbl_'s blog

By lvisbl_, history, 3 days ago, In English

Recently, I have encountered this Floyd Warshall problem, that the problem adds extra constraint on the shortest path (all edge weights + 1 largest vertice on the path). Following my understanding, Floyd Warshall is dynamic programming and when we "relax" the state, I will add that extra condition.

So, I call dp[i][j][k]: the min distance between i and j vertices, and the middle vertices consisting only the first k vertices. And maxCost[i][j][k] is the max cost vertice of the path I have chosen in dp[i][j][k]. So my transition:

if (dp[i][j][k] + maxCost[i][j][k] > dp[i][k][k — 1] + dp[k][j][k — 1] + max(maxCost[i][k][k — 1], maxCost[k][j][k — 1]) or if the last chosen path for two vertices i and j has larger cost for the path for i, j and k is in the middle of the path, then I relax distance between i and j, and set new maxCost for that path. But there is problem with this logic can you help to point it out. Thank!

Code
  • Vote: I like it
  • +10
  • Vote: I do not like it

»
3 days ago, # |
  Vote: I like it +25 Vote: I do not like it

Consider this test case:

5 5 1
100 1000 1 1 10000
4 1 10
1 3 10
4 2 1
2 3 1
3 5 1
4 5

Your code prints 10021, but I think the correct answer is 10003. If I understand your logic correctly, here is your problem: you calculate dp[4][3][3] to be 20 (and not 2): even though $$$4 \to 2 \to 3$$$ has edges summing to only 2, the feast at 2 would cost 1000, meanwhile by going $$$4 \to 1 \to 3$$$ you pay 20 for the edges but 100 for the feast. Here's why this breaks: once you include 5, the feast will be held there and it turns out that going $$$4 \to 2 \to 3$$$ would have been cheaper after all.

Here's how I would solve this problem
  • »
    »
    3 days ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Thank you so much for pointing it out, I have understood why my logic failed. But during debug this kind of problem, it took me so much time and still did not know where the logic failed. So, another question.. How do you come up with the test case.

    • »
      »
      »
      3 days ago, # ^ |
        Vote: I like it +1 Vote: I do not like it

      Experience I guess. After reading what you said in the blog I quickly thought "but what if you choose a more expensive path because it has a cheaper feast, and then it turns out you won't use that feast anyway". Then I just constructed a test case to prove that this can happen.

      What you also can do is:

      • write a very naive solution (try all paths or something) or copy someone else's if you can
      • write a program to generate thousands of small test cases
      • use those two to find a test case where your solution gives the wrong answer.
      • »
        »
        »
        »
        2 days ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Thank you so much, I have got AC following you suggestion and it's satisfied me enough.

        Btw just for curiosity, below, I have sent another code which run the same failed logic two times and it is working (got AC too). It's like some kind of convergence because of two parameters depend each other (min dist and max cost), but I have no idea how it's work.

  • »
    »
    3 days ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    Hi, I have this arbitrary code from my peer and with the same idea, he said that if I run Floyd 2 times, the logic will work. Can you help to explain this..

    code