【競プロ】グラフ問題の苦手克服がしたい

スポンサードリンク

こんにちは。ふぁんたです。

 

競技プログラミングのスキルを上げたい。

 

急に思い立ったので、一問手を出しました。

Atcoder Regular Contest 034 C – One-stroke Path

問題文概要

無向グラフの頂点数N、辺の数Mが最初に与えられる。

その後、M個のノードの情報が与えられる。

1番の頂点から始めて、全部の頂点を通るルートはなんパターンあるか出力せよ。

 

 

 

結構時間がかかりましたが、実装できました。

 

それでは、解説を見ていきます。

 

 

解説を見ると、深さ優先探索の再帰関数で解いています。

 

ABC054の解説PDFより引用

 

 

探索し終わったノードに関しては9行目、深さ優先探索後に一つ上のノードに抜けています。こんなにきれいに書けるんですね。

日本語が混ざっていますが、12行で簡潔に書けるというのは想像していませんでした。

 

 

 

自分の実装について。

 

…自分が「グラフ問題が苦手だから」なのか、「DFS(=深さ優先探索)になれていないから」なのか、「クラスの実装、コンストラクタの作成を覚えて使いたいだけだから」なのかわからないのですが、めっっっっっっちゃ長くなりました。

 

考え方としては、

「ノードの通し番号と、次のノードのリストを保持するクラス Nodes」と

「今どこのノードにいて、今までどのノードを通ってきたかという履歴情報を持つ、ノード間を移動する人を生成するクラス Person」を使って、

 

1のノードにPersonを一人置いて、人の列を作ります。

 

この人の列がなくなるまで、

・人を一人取り出して、それが全ノード制覇済みの履歴を持っていたら出力する数字を+1します。

・そういう履歴を持っていなかったら、繋がっているノードのうち、訪問していないノードのリストを作ります。

・リストの中のノードの数だけ人間を複製し、

・分岐先に訪問した情報を各人の履歴情報に書き込んで移動させる

ということを繰り返します。

 

 

ACしました。

 

ACはできたんですが、こう書いてしまうのを治していきたいんです。

 

まず、C#にグラフを扱う方法はないのか? という疑問があります。

配列とか、Dictionary(連想配列)とかListとか、大事だなあ、便利だなあと思うデータの扱い方があるんですが、グラフはどう扱えばいいんでしょう。

今回はnodesクラスを実装してやりきりましたが、時間がかかるんです。

 

 

次に、クラス使うべきか?というのも思うところではあります。

 

模範解答のPDFに、こんなに長いコードは見たことがありません。

 

しかも、思いついて書いてACするまでに1時間弱ほどかかっているんです。

速さ、正確さを競いたいコンテストで、走るフォームがきれいとかそういうことを言っても仕方がないので治したいなあと思うんです。

 


ときどき、300点400点ぐらいの問題を解いてみるってのはいいですね。優先探索とか、再帰とか、忘れかけそうなものを思い出せますし、自分で反省するべき材料がこんな感じに見つかることにもなります。

 

またやります。

スポンサードリンク