raYRS2geSiiPYP4D's blog

By raYRS2geSiiPYP4D, history, 7 days ago, In English

i work out CSES set and decided to share my short editorial for Planets Queries II because i learnt some useful matter (and unfortunately arham_doshi's list does not include this problem);

the problem gives a n nodes and n edges; such graph is called functional graph; thus, can be derived that: a fg would have at least one cycle, every cycle would be in form of a circle and every uncycled edge would be directed toward a cycle;

the problem is included into usaco's binary jumping problem list; previously, i have experienced problems with lca in tree where bin jumps have been used to find distance between nodes (jump from src to lca and lca to dst); however, a fg cannot be rooted because it might form a big circle; thus, a binary jump table supposed to be used to reach a set of cycled nodes (multiple entry points) rather than a root node;

moreover, a fg might have multiple cycles and as the result the other (uncycled) nodes might form some trees which would have cycled nodes as their root nodes (some info about that in usaco guide's solution);

based on such observations it could be concluded that 4 cases supposed to be handled: src and dst are cycled; src and dst are uncycled; src is cycled and dst is not; src is uncycled and dst is cycled;

the first approach which supposed to be considered when dealing with cycles would be traversing nodes in topological order (dfs or khan); for this problem i figured out that khan's algo would be useful;

khan's algo processes 0-indegreed nodes (no incoming edge) using a queue; each dequeued node is used to traverse over it's edges and to decrement indegree of edges, then algo enqueues edges with 0-indegreed; this is useful: processing order would be a topologically sorted sequence (leaves first), unprocessed nodes would form a cycled set;

if process topo sorted sequence backwards (after knan's execution) then nodes which would be closer to a cycled root would be processed earlier rather than the other nodes; based on such guarantee a uncycledDistTo[] and a uncycledRoot[] can be derived: uncycledRoot[u] = uncycledRoot[jmp[u][0]] and uncycledDistTo[u] = uncycledDistTo[jmp[u][0]] + 1;

at this point (having uncycledRoot and uncycledDistTo) -1 response would be instantly returned to such queries as: dst and src are belongs to different tree (has different roots); src is cycled and dst is uncycled (edges directed toward cycles); dst distance is longer than src distance (dst would be behind); src != dst but both belong to same tree and have same distance to rooted cycled edge;

moreover, if src and dst belong to a same tree, then src can jump for a difference between distances of src and dst; if src would be equal to dst after jump then a query answer would be jump length otherwise it would be -1;

having a set of cycled nodes and choosing arbitrary start of a cycle cycledStart[], cycledDistTo[] and cycledLen[] arrays would be derived; cycledStart would have information about a cycle leader and would be used to check if nodes belong to a same cycle; cycledDistTo would store distance from each cycled node to a leader, this info would would used to calculate the shortest distance between src and dst in directed cycle; cycledLen would have a total number of nodes in each cycle which assigned to a cycle's leader, this info would be complement cycledDistTo;

having this information (cycledStart, cycledDistTo, cycledLen) all cycle-related queries would be processed; if both src and dst belongs to the different cycle (different cycle leader) then a query response would be -1;

if src and dst belongs to a same cycle, then distance between dst and src would be answer (cycledDistTo[dst] - cycledDistTo[src]); however src might be more distantly located from an entry point and difference would be negative, to handle such case (cycle would be circle) distance would be added and module operation applied: (dist1 - dist2 + len) % len;

the last query would be src for uncycled src and cycled dst; uncycled src would jump in cycle entry point; if entry point and dst would belong to a same cycle, then answer would be distance between dst and entry point (explained above) + jump length;

code:

Spoiler

thank you and have a good day;

Full text and comments »

  • Vote: I like it
  • 0
  • Vote: I do not like it