この問題は UnionFind(素集合データ構造)、逆の操作 を問います。

問題文では辺を削除する、といった操作が必要になりますが、この操作の実装は容易ではありません。
なので、次のように逆の操作をする方が良さそうです。

  • すべてのイベントが終わった後の状態のグラフを構築し、与えられるグラフの辺の情報を矛盾なく追加していく

「すべてのイベントが終わった後の状態」とは、辺の情報に頂点番号 x1,x2,...,xQx_1,x_2,...,x_Q が含まれていた時、その辺は採用されていないグラフを言います。
その後、イベントでは j=1,2,...,Qj=1,2,...,Q として行っていましたが、逆の操作のため j=Q,Q1,Q2,...,1j'=Q,Q-1,Q-2,...,1 の順で、次の操作を行います。

  • 頂点 xjx_{j'} をグラフに追加する、すなわち xjx_{j'} を含む辺を追加していく

こうして操作後にできるグラフは入力に与えられたグラフと等しくなります。よってこの逆の操作が適切であることがわかります。

また Qj(=j)Q-j'(=j) 回目の操作毎に、毎回頂点 11 から頂点 NN へのパスの存在判定を、DFSなどの探索法を用いると最悪 O(Q(N+M))O(Q(N+M)) だけかかり、時間制限に間に合いません。なのでこの判定を高速に行う必要があります。

そこで、伝家の宝刀であるUnionFind(素集合データ構造)を用いることで、この判定を O(α(N))O(\alpha(N)) ※で実装することができます。

最終的に答えるべき値は、この操作をはじめ、初めて頂点 11 から頂点 NN をつなぐパスが存在するときの jj'JJ とおくと、QJQ-J となります。なおこの判定がすべての jj' に対し、頂点 11 から頂点 NN をつなぐパスが存在するなら、答えは Reachable となります。

以上からこの問題は O(M+Qα(N))O(M+Q\alpha(N)) で実装することができました。以下が解答例になります。

  • C++
  • Python