Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

(ブログ用)Codeforces #400 D. The Door Problem

347 views

Published on

ブログ用の記事です。
2-SATの、より簡単な場合についての解説です。

Published in: Education
  • Be the first to comment

  • Be the first to like this

(ブログ用)Codeforces #400 D. The Door Problem

  1. 1. Codeforces #400 D. The Door Problem satanic @satanic0258
  2. 2. 🔓 🔒 🔓 A B C 以下の例(サンプル2)を例にとって解説していきます。 なお今後、下の図において、 ・黒は未決定の状態 ・橙はオンにした状態 ・青はオフにした状態 を表します。 a c b
  3. 3. 🔓 🔒 🔓 A B C まずAを押した場合、Aは全てのドアに繋がるため、 全てのドアの状態が反転します。 a c b 初期状態
  4. 4. 🔒 🔓 🔒 A B C まずAを押した場合、Aは全てのドアに繋がるため、 全てのドアの状態が反転します。 a c b 初期状態
  5. 5. 🔒 🔓 🔒 A B C まずAを押した場合、Aは全てのドアに繋がるため、 全てのドアの状態が反転します。 すると、aはオフになってしまいました。 aをオンにするにはCもオンである必要があります。 a c b 初期状態
  6. 6. 🔒 🔓 🔒 A B C まずAを押した場合、Aは全てのドアに繋がるため、 全てのドアの状態が反転します。 すると、aはオフになってしまいました。 aをオンにするにはCもオンである必要があります。 Cをオンにしました。 それに伴って、ドアの状態は… a c b 初期状態
  7. 7. 🔓 🔓 🔓 A B C まずAを押した場合、Aは全てのドアに繋がるため、 全てのドアの状態が反転します。 すると、aはオフになってしまいました。 aをオンにするにはCもオンである必要があります。 Cをオンにしました。 それに伴って、ドアの状態は次のようになります。 a c b 初期状態
  8. 8. 🔓 🔓 🔓 A B C 今、考慮していないcの状態も変わりましたが、 結果的にcも開いている状態になったのでよしとします。 a c b 初期状態
  9. 9. 🔓 🔓 🔓 A B C これで、全てのドアが開いている状態になりました。 Bの状態がまだ決まっていませんが、 bは片方が決まっていて開いているため、 bに繋がっているBはオフとなります。 a c b 初期状態
  10. 10. 🔓 🔓 🔓 A B C これで、全てのドアが開いている状態になりました。 Bの状態がまだ決まっていませんが、 bは片方が決まっていて開いているため、 bに繋がっているBはオフとなります。 よって、ドアを全て開いた状態にするスイッチの組み合わせ があることが分かりました。 a c b 初期状態
  11. 11. この問題を、グラフ上で解いてみましょう。 初期状態
  12. 12. この問題を、グラフ上で解いてみましょう。 2-SATをグラフに帰着するとき、オン/オフの状態を 決めるものそれぞれについて、オンの頂点とオフの頂点を 作ります。 初期状態 A A B B C C
  13. 13. この問題を、グラフ上で解いてみましょう。 2-SATをグラフに帰着するとき、オン/オフの状態を 決めるものそれぞれについて、オンの頂点とオフの頂点を 作ります。 ここで、オンの頂点はそのまま、 オフの頂点には上にバーを付けることにします。 初期状態 A A B B C C オン→ オフ→
  14. 14. では、このグラフに辺を張っていきます。 初期状態 A A B B C C オン→ オフ→
  15. 15. では、このグラフに辺を張っていきます。 まずAをオンにすると、a,cを介して繋がるCもオンにする 必要がありました。 そのため、A→Cと辺を張ります。 初期状態 A A B B C C オン→ オフ→
  16. 16. では、このグラフに辺を張っていきます。 まずAをオンにすると、a,cを介して繋がるCもオンにする 必要がありました。 そのため、A→Cと辺を張ります。 また、bを介して繋がるBはオフにする必要がありました。 そのため、A→Bと辺を張ります。 初期状態 A A B B C C オン→ オフ→
  17. 17. 同様に、各頂点について辺を張っていきます。 初期状態 A A B B C C オン→ オフ→
  18. 18. 同様に、各頂点について辺を張っていきます。 Bをオンにすると、Aはオフにする必要があります。 従って、B→Aと辺を張ります。 初期状態 A A B B C C オン→ オフ→
  19. 19. 同様に、各頂点について辺を張っていきます。 Bをオンにすると、Aはオフにする必要があります。 従って、B→Aと辺を張ります。 Cをオンにすると、Aはオンにする必要があります。 しかし、これについては既に調べてあるため、 わざわざ二重に辺を張る必要はありません。 初期状態 A A B B C C オン→ オフ→
  20. 20. Aをオフにすると、Cもオフにする必要があります。 従って、A→Cと辺を張ります。 初期状態 A A B B C C オン→ オフ→
  21. 21. Aをオフにすると、Cもオフにする必要があります。 従って、A→Cと辺を張ります。 Bをオフにした場合、Cをオフにした場合については、 既に調べられている状態になっているため、 グラフ上に変化はありません。 初期状態 A A B B C C オン→ オフ→
  22. 22. こうして全ての辺を張ることが出来ました。 初期状態 A A B B C C オン→ オフ→
  23. 23. こうして全ての辺を張ることが出来ました。 このグラフを見ると、つじつまが合うようなスイッチの 組み合わせは全て同じ連結成分になっており、 逆に矛盾が発生するような頂点同士は連結になっていない ことが分かります。 初期状態 A A B B C C オン→ オフ→
  24. 24. こうして全ての辺を張ることが出来ました。 このグラフを見ると、つじつまが合うようなスイッチの 組み合わせは全て同じ連結成分になっており、 逆に矛盾が発生するような頂点同士は連結になっていない ことが分かります。 では、ある頂点と連結になっている頂点を全て抜き出せば それが正しい組み合わせとなるのでしょうか? 初期状態 A A B B C C オン→ オフ→
  25. 25. そうとは限りません。 右の図のように、連結成分の中には 「AがオンならばAをオフにしなければならない」 といったおかしな部分が出ることがあります。 初期状態 A A A A B B C C オン→ オフ→
  26. 26. そうとは限りません。 右の図のように、連結成分の中には 「AがオンならばAをオフにしなければならない」 といったおかしな部分が出ることがあります。 逆に言えば、グラフにこのような矛盾が無ければ 正しいスイッチの組み合わせがあるとわかります。 初期状態 A A A A B B C C オン→ オフ→
  27. 27. 今回の例では、 AとA、 BとB、 CとC、と全ての頂点で、 別々の連結成分に属していることが分かります。 初期状態 A A B B C C オン→ オフ→
  28. 28. 今回の例では、 AとA、 BとB、 CとC、と全ての頂点で、 別々の連結成分に属していることが分かります。 よって、グラフからこの例では正しいスイッチの 組み合わせが存在することが分かりました。 初期状態 A A B B C C オン→ オフ→
  29. 29. 🔓 🔒 🔓 A B C では、今度は以下の例(サンプル1)について 見ていきます。 a c b 初期状態
  30. 30. では、今度は以下の例(サンプル1)について 見ていきます。 スイッチ数は先ほどと同じなため、グラフの初期状態も 同じとなります。 初期状態 A A B B C C オン→ オフ→
  31. 31. まずAをオンにした場合について考えます。 Aはaを介してBに、またcを介してCに繋がっています。 初期状態 A A B B C C オン→ オフ→
  32. 32. まずAをオンにした場合について考えます。 Aはaを介してBに、またcを介してCに繋がっています。 従って、AをオンにするとBとCもオンにする必要があるため、 A→B、A→Cと辺を張ります。 初期状態 A A B B C C オン→ オフ→
  33. 33. まずAをオンにした場合について考えます。 Aはaを介してBに、またcを介してCに繋がっています。 従って、AをオンにするとBとCもオンにする必要があるため、 A→B、A→Cと辺を張ります。 同様に、BをオンにするとAはオンに、Cはオフにする必要が あるため、B→A、B→Cと辺を張ります。 (A-B間は既に辺が張ってあるため実際には張りません) 初期状態 A A B B C C オン→ オフ→
  34. 34. 同様に、 初期状態 A A B B C C オン→ オフ→
  35. 35. 同様に、C、 初期状態 A A B B C C オン→ オフ→
  36. 36. 同様に、C、A、 初期状態 A A B B C C オン→ オフ→
  37. 37. 同様に、C、A、B、 初期状態 A A B B C C オン→ オフ→
  38. 38. 同様に、C、A、B、Cについても辺を張ります。 初期状態 A A B B C C オン→ オフ→
  39. 39. 同様に、C、A、B、Cについても辺を張ります。 こうして、全ての辺を張ることが出来ました。 では、どの頂点が連結になっているでしょうか。 初期状態 A A B B C C オン→ オフ→
  40. 40. 同様に、C、A、B、Cについても辺を張ります。 こうして、全ての辺を張ることが出来ました。 では、どの頂点が連結になっているでしょうか。 ある頂点から初めて辺を順に辿っていくと分かりますが、 この例では、全ての頂点が連結となっています。 初期状態 A A B B C C オン→ オフ→
  41. 41. 特に、AとAが同じ連結成分に属しているため、 この例では正しいスイッチの組み合わせが存在しない ことが分かります。 初期状態 A A B B C C オン→ オフ→
  42. 42. 特に、AとAが同じ連結成分に属しているため、 この例では正しいスイッチの組み合わせが存在しない ことが分かります。 このように、グラフに帰着してこの問題を 解くことが出来ます。 初期状態 A A B B C C オン→ オフ→
  43. 43. 実際にプログラムを実装する際には、 ・グラフに辺を追加する ・ある2頂点が連結であるかを調べる というクエリをこなすデータ構造である、素集合森 (通称Union-Find)を使うと良いでしょう。 初期状態 A A B B C C オン→ オフ→
  44. 44. その後、AとAが同じ連結成分に属しているか否かを 調べることで組み合わせの存在を調べます。
  45. 45. ※注意※ しかし、この問題で現れる論理式は、 ・同値 ( ⇔ )…両方押すか押さないか ・排他的論理和(XOR)…どちらか片方だけ押す の積となっています。
  46. 46. おわり

×