USACO Training "Fence Loops" and the Workings of Floyd-Warshall's Algorithm
Floyd-Warshall's
for k in 1-N do:for i in 1-N do:
for j in 1-N do:
d[i][j] := min(d[i][j], d[i][k]+d[k][j])
Why it Works
Floyd-Warshall's is an algorithm for computing all-pairs shortest paths, taking a DP approach: selct any "middle node" K and two nodes I and J in which you'd like to calculate the shortest path for, and then define the shortest path between I and J as whichever is smaller, the current shortest path betwen I and J OR the current shortest path between I and K plus the current shortest path between K and J.At first this may seem obvious. Let's delve into why it works.
If we iterate K from the beginning (1 to N), at any given point in time whilst K is strictly less than a definite number X, we can say that the current shortest path between any two nodes I and J (regardless of whether I=X or J=X) that the current shortest path will NOT include X. The start and end nodes may include X, but no node in between will be X.
The DP approach - 3 parameter version
Of course we need to understand the three-parameter version!Let D(i, j, k) represent the shortest path between i and j passing only through vertices between 1 and k, inclusive.
Assume that we have an oracle, knowing all the shortest paths.
Let us define D recursively:
Case 1: the shortest path between i and j does not pass through k
The answer will be D(i, j, k-1) since we can shorten the vertice set to between 1 and k-1, inclusive - the shortest path will not pass through k.
Case 2: the shortest path between i and j will pass through k.
Since using Floyd-Warshall's for SP implies there are no negative weight loops, it is optimal to pass through k exactly once. In other words, the shortest path between i and k as well as the shortest path between k and j will not pass through k. Let us cut the shortest path into two shortest paths that share a endpoint k. The length of the shortest path between i and j can be defined as the shortest path between i and k plus the shortest path between k and j. As such, the answer is D(i, k, k-1) + D(k, j, k-1).
So why do we only need two parameters in the real (array-based, not recursive) version? That is because we will make a whole new layer that only depends on the previous layer, so we might as well overwrite the entire array each time, using what was previously in the array to calculate the new value.
Minimum Loop
The key to doing the minimum loop problem is realizing that if we update the Floyd-Warshall state for an edge, we may no longer use that edge!Therefore, we must update the minimum perimeter before updating the shortest path for any distance I~J; a recurrence equation is as follows:
minimum perimeter = min(minimum perimeter, un-updated shortest path between i~j plus input distance between i~k plus input distance between k~j)
Then, we can safely update the shortest paths.
UVA 808
The first and most important part is to convert the nasty hexagonal grid into a normal two-dimensional array. In the example image, we can convert it into something that looks like this:There is a subtle patten: given a point x, instead of normally spiraling (or snaking, whatever you prefer) , we need to spiral in diagonals (for example, between 1 and 2 is a diagonal, ans the same goes for 3 to 4). This then becomes a simple ad-hoc problem, but we still need to find out the distance!
Finding Distance
(the 2-D grid, with 1 in the center, and red and blue lines as rows and columns, respectively and green diagnols going from upper-left to lower-right)We clearly can't use normal Euclidean (aka sidewalk) distance, because in the real picture, the hexagons connect in 6 ways; therefore, you can walk diagonally (along the green lines) and have it still count as one whole step!
Therefore, the problem boils down into calculating the shortest distance between two coordinates if you can go on the red, green, and blue lines. This can still be solved mathematically!
Comments
Post a Comment