Hints for SRM 576, D2, 500-Pointer (ArcadeManao)

James S. Plank

Wed Oct 30 12:04:05 EDT 2013
Problem Statement.
Were I to give you a value of L, and ask you if Manao can get the coin, this would be a very simple DFS problem. As always, with a DFS, you need to ask yourself what the best way is to structure the graph. Here's what I suggest:

Create a graph from the problem specification, where each node contains two adjacency lists: one for horizontal edges, and one for vertical edges. Horizontal edges are easy -- you can be connected horizontally either to the cell on your left or your right. Vertical edges are a little trickier. You should have a vertical edge to the first platform above you, and the first platform below you. Record the length of that edge.

For example, here would be the graph from the problem statement (Example 0):

Now, given a value of L, you can do a DFS to determine whether the starting node is connected to the coin node. When you do your DFS, you do not traverse vertical edges that are longer than L.

What's the running time complexity of that? Well, |V| and |E| are both bounded by MN, so it is O(MN).

If you do this for every value of L from 1 to N, then the running time complexity is O(N2M). In our constraints, the maximum value for N and M is 50, so this value is 125,000, well within the constraints.

Give it a try.


Two improvements

While these are not necessary for Topcoder, there are two improvements that you can do. First is to perform a binary search on L. That is O(NM log(N)).

Second is to structure the problem differently. Instead, suppose you build the graph incrementally. You start with a graph with all nodes and no edges. For example, here is Example 0:

Now, add all edges of size 1, and for each of these, determine connected components with disjoint sets. You can treat the graph as undirected this time. Each time you add an edge, you test to see if it connects nodes in different disjoint sets. If so, you perform Union. When you are done with the edges of size 1, you see if the starting node and the coin node are in the same disjoint set. Here's the graph after adding the edges of size 1:

The starting node and the coin are not in the same disjoint set, so you continue adding edges of size two:

The starting node and the coin are in the same component. We're done, and L=2.

Now, what's the running time complexity of this? Well, we have to sort the edges, which is O(|E| log(|E|)). Then we do up to 2|E| find operations and up to |V|-1 union operations. That means:

O(|E| log(|E|)) + O(|E|) + O(|V| α(|V|))

The dominant cost here is sorting, so it is O(|E| log(|E|)).