We can simply modify the travelling salesman problem to get whether a Hamilton walk exists or not in O(2^N * N^2)Time Complexity.
But I read it at codeforces that it is possible to solve this problem in O(2^N * N) Time .
Although , I cannot understand the state they are considering, but they are kind of compressing the original state of Travelling Salesman Problem.
Can someone give me a detailed explanation, I am new to bitmasking + DP (Infact I started today :D)
If you want you can look Point 4 at Codeforces
Terminology:
binary (x) means x is based 2.0mask always represent a set of nodes. A node i is in mask means 2^i AND mask != 0. In the same way set mask-i (here - means removing i from the set) can be represented as mask XOR 2^i in bitmask.Let mask be the bitmask of a set of nodes. We define dp[mask] as the bitmask of another set of nodes, which contains a node i if and only if:
i in maskmask, which ends in node iFor example, dp[binary(1011)] = binary(1010) means that a hamilton walk exists for binary(1011) which ends in node 1, and another hamilton walk exists for binary(1011) which ends in node 3
So for N nodes, a hamilton walk exists for all of them if dp[2^N - 1] != 0
Then as described in the Codeforces link you posted, we can calculate dp[] by:
When mask only contains one node i
dp[2^i] = 2^i(which means for a single node, a walk always exists, and it ends at itself.
Otherwise
Given
mask, by definition ofdp[mask], for every nodeiinmask, we want to know if a walk exist formask, and ends ati. To calculate this, we first check if any walk exists for the set of nodesmask-i, then check among those walks ofmask-i, if there's a walk ends at a nodejthat's connected toi. Since combining them gives us a walk ofmaskthat ends ati.To make this step faster, we pre-process
M[i]to be the bitmask of all notes connected toi. Soiindp[mask]ifdp[mask XOR 2^i] AND M[i] != 0.To explain a bit more about this step,
dp[mask XOR 2^i]is the set of nodes that walk ofmask-ican end, andM[i]is the set of nodes that's directly connected toi. So theANDof them means if any walk ofmaskthat ends iniexists.
dp[] is O(2^N) in space.
Calculating dp[] looks like
for mask = range(0, 2^N):
for i in range(0,N):
if 2^i AND mask != 0: # Node i in mask
if (mask only has one node) || (dp[mask XOR 2^i] AND M[i] != 0):
dp[mask] = dp[mask] OR 2^i # adding node i to dp[mask]
Which is O(2^N * N)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With