Блог пользователя Fork512Hz

Автор Fork512Hz, история, 8 месяцев назад, По-английски

Problem:

Given a directed graph and $$$q$$$ queries. For each query, you need to answer whether a path exists from point $$$x$$$ to point $$$y$$$. Each query needs to be processed within $$$O(1)$$$.

A BF solution is, we can do $$$V$$$ DFSs from every vertex and set the bits in the answer matrix for each visited vertex, and the complexity of preprocessing is $$$O(V^2)$$$. You can do some optimizations to reduce the steps taken in the traversal by a lot, but as long as you store the answer in a matrix, $$$O(V^2)$$$ space complexity leads to an inevitable $$$O(V^2)$$$ time complexity.

Now the question is: is it possible to do the preprocessing within less than $$$O(V^2)$$$ time, or at least, less than $$$O(V^2)$$$ space? At least, if queries are to be processed online, it seems highly improbable.

I wrote DAG in the title, because we can run Tarjan's to find out SCCs and if $$$x$$$ and $$$y$$$ belong to the same SCC it's a clear YES.

UPD: There seems to be some paper on this: Paper

  • Проголосовать: нравится
  • +2
  • Проголосовать: не нравится

»
8 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

trick 1 from this blog

  • »
    »
    8 месяцев назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    I think this only reduced the constant factor, instead of the complexity

    • »
      »
      »
      8 месяцев назад, # ^ |
        Проголосовать: нравится +6 Проголосовать: не нравится

      It reduces the time complexity from $$$O(n^2)$$$ to $$$O(n^2/ \log{n})$$$ and memory from $$$O(n^2/ \log{n})$$$ to $$$O(n)$$$.

      If you want to reduce the time complexity even further, consider getting treatment to increase your IQ and invent a way yourself.

      • »
        »
        »
        »
        8 месяцев назад, # ^ |
        Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

        Well, reducing from bitset<V> to long long[V/64] does not necessarily cut the space cost by an order of complexity.

        • »
          »
          »
          »
          »
          8 месяцев назад, # ^ |
            Проголосовать: нравится -13 Проголосовать: не нравится

          Did you even read the blog?

          Stop asking questions if you do not want to listen to the answers.

          If you read the blog and do not understand why the space taken is only $$$O(n \log{n} / \log{n}) = O(n)$$$, then you are probably too weak to understand this technique right now, try again later.

»
8 месяцев назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

I mean we can use optimized Disjoint Set Union? For every edge, do union_sets(u, v).

Now when given a query, check if find_set(u) == find_set(v)? This will achieve almost O(1) time complexity for each query and O(n) space complexity. Learn more about TC here.

Edit:

I noticed that you were asking for DAG, this approach would work for undirected graph.

»
8 месяцев назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Compress graph to DAG first

Now store N bitsets, with bits representing reachable nodes from u. Now for each u simply do dp[u] |= dp[v]. Which will have O(n^2/32) both time and space complexity, but in practice it'll work extremely fast for even N <= 10^5 and sometimes even 2*10^5, depending on constraints and compiller. Common practice is to use pragma (target "popcount" if I remember correctly). Iirc you can't do it any better unless graph has some special structure