質問の概要
トポロジカルソートと DFS に関する問題で、AC コードで考慮できていて WA コードでは考慮できていないケースパターン (グラフの例) を教えてほしいです。
問題
AtCoder Beginner Contest 315: E - Prerequisites の問題を解きました。
https://atcoder.jp/contests/abc315/tasks/abc315_e
問題文を要約すると、以下のようになります。
有向非巡回グラフ (ただし連結成分が 1 つとは限らない) が与えられる。ノード 1 から到達できるノード集合に対してトポロジカルソートを行い、ソート結果を出力せよ。
方針
以下の方針でこの問題を解きました。
- ノード 1 と同じ連結成分に含まれるノードを全列挙する必要がある。これをノード 1 を 始点 とした有向グラフを構築し、そのグラフ上で DFS を行うことで実現する。
- ノード 1 が 終点 となる方向でトポロジカルソートを行う必要があるため、手順 1 とは逆方向の有向グラフを構築し、そのグラフ上でトポロジカルソートを行う。
- トポロジカルソート時に訪れる対象となるノードは、手順 1 の DFS で到達できたノードに限定しなければならない。
疑問点
この考えを元に実装したコードが以下になりますが、WA となりました。
https://atcoder.jp/contests/abc315/submissions/44743639
こちらは上記コードを修正し、AC となったコードです。
https://atcoder.jp/contests/abc315/submissions/44773681
違う点はトポロジカルソート関数中のコメントが書かれた if
の条件だけです。正確には出力部分も微妙に異なりますが、おそらく本質ではない箇所だと思われます。
cpp
1vector<int> topological_sort(vector<vector<int>> &graph, vector<int> °, vector<int> &visited){ 2 int len=graph.size(); 3 vector<int> res; 4 5 queue<int> que; 6 rep(i,1,len){ 7 if(deg[i]==0&&visited[i]) que.push(i); 8 } 9 10 while(!que.empty()){ 11 int v=que.front(); que.pop(); 12 rep(i,0,int(graph[v].size())){ 13 int u=graph[v][i]; 14 deg[u]--; 15 // if(deg[u]==0) que.push(u); // WA コードはこっち 16 if(deg[u]==0&&visited[u]) que.push(u); // AC コードはこっち 17 } 18 res.push_back(v); 19 } 20 21 return res; 22}
WA コードでこのように if
の条件を設定した理由ですが、トポロジカルソート開始前に探索開始箇所を queue に入れる際、7 行目の if
で DFS で到達できたノードだけを入れているため、while
部分で辿られるノードはそこから繋がるノード、つまり DFS で到達できたノードしか有り得ないと考えたからです。
ですが、while
部分にも「DFS で到達できたか?」の条件を加えることで AC となったため、上記の考えは誤りだったと考えています。
そこで、WA コードで上手く答えを出せないグラフの例を考えてみたのですが、一向にわかりません。どなたかわかる方はいらっしゃいますでしょうか?

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/08/24 03:37 編集