Swistakk's blog

By Swistakk, history, 9 years ago, In English

Yesterday at SRM 670 I got a funny story which I want to describe. During challenge phase I noted that one solution of medium problem in my room uses Floyd-Warshall. I thought "Oh, why haven't I thought about it during coding phase? Much shorter than those DFSes!", but then I noted that unexpectedly this infamous order of loops is not correct. It went like this:

FOR(x, n) FOR(y, n) FOR(z, n) dis[x][y] = min(dis[x][y], dis[x][z] + dis[z][y]);

while everyone should know that FOR(z,n) should be the outer loop, not the inner one. I tried to hack this solution, so I inputted graph 0-3-2-1, however my test was rejected, because problem was about trees and there was a constraint that parent of vertex i should be less than i and I didn't have time to come up with another testcase. Unexpectedly, this solution passed systests! I thought that its author is very lucky. However it turns out that for trees with this constraint this order of loop result in computing correct distances!

What we need to ensure is that we will somehow detect this one particular path during execution of that algorithm. With this order of loops it consecutively tries to compute distances dis[0][0], dis[0][1], ... dis[0][n — 1], dis[1][0], etc. in lexicographical order. Initialization consists of conditions dis[i][i] = 0, dis[x][y] = dis[y][x] = 1 iff <-> x-y is an edge. We will inductively (on lexicographical order) prove that it computes correct distances. Assume that x-y is not an edge.

Consider two cases:

  1. y is not a descendant of x
    Let z be parent of x. We have z < x, so (x, y) > (z, y) (lexorder of pairs), so dis[z][y] was already computed and x-z is an edge, so both dis[x][z] and dis[z][y] are valid values, so we will detect that path when looking at z.
  2. y is descendant of x
    Let z be parent of y. We have z < y, so (x, z) < (x, y), so dis[x][z] was already computed and z-y is an edge, so both dis[x][z] ad dis[z][y] are again valid values and we are done.

Funny how bugged version of Floyd-Warshall turns out to be correct on trees with this weird constraint on parents :P.

  • Vote: I like it
  • +152
  • Vote: I do not like it

»
9 years ago, # |
  Vote: I like it +40 Vote: I do not like it

Funny indeed :P

The pattern of replacing DFSs by Floyd-Warshall is really common in TC, in which the number of nodes is almost always limited to 100 or less, so it's a good trick to know.

I don't think this is a bad thing either -- if you know the solution by FW, you clearly know the solution by DFS too, it would just give you more trouble coding. And simplifying implementation is always a good thing in my book.

»
2 months ago, # |
  Vote: I like it +37 Vote: I do not like it

Looks like a hackercup problem to me :D

  • »
    »
    2 months ago, # ^ |
    Rev. 2   Vote: I like it +9 Vote: I do not like it
    • »
      »
      »
      2 months ago, # ^ |
        Vote: I like it +38 Vote: I do not like it

      Thanks, it's actually the first time ever for me to qualify to the final of one of the most prestigious individual competitions (I'd count GCJ, TCO, FBHC and AGC-WTF for that), so I am very happy ^^ (though I did qualify for DCJ in 2017 if we count this one). I even thought about your comment after the contest :D

      • »
        »
        »
        »
        2 months ago, # ^ |
          Vote: I like it +20 Vote: I do not like it

        What, first time? It's long overdue then, good job finally getting it! :)

        • »
          »
          »
          »
          »
          2 months ago, # ^ |
            Vote: I like it 0 Vote: I do not like it

          Haha, yeah, thanks :) I don't think I'm good enough to deserve more than O(1) finals of these, but not getting even one was indeed unlucky. Year ago it was one spot off by 44 seconds, once it was local stack limit (embarrassing :p), a couple times it was one big away etc. :p... 25th place in finals, here I come!

»
2 months ago, # |
  Vote: I like it +59 Vote: I do not like it

Another fun fact about Floyd-Warshall is that if you have any order of the for loops and just repeat the code 3 times it will always yield correct answers.