C++ グラフ・探索
参考サイト
DFS (深さ優先探索) 超入門! 〜 グラフ・アルゴリズムの世界への入口 〜【前編】 - Qiita
グラフを隣接リストで表す
隣接リストは、各頂点毎に、隣接する頂点の配列を作ります。
#include <bits/stdc++.h>using namespace std;using Graph = vector<vector<int>>;
int main(){ Graph G; G.at(0) = {1, 2}; G.at(1) = {0, 2, 3}; G.at(2) = {0, 1, 4}; G.at(3) = {1, 4, 5}; G.at(4) = {2, 3, 6}; G.at(5) = {3}; G.at(6) = {4};}0と1はお互いがお互いを配列に入れてるので、これは無向グラフ。有効グラフの場合はどちらかに入る。
BFS(幅優先探索)
サンプルコード
#include <bits/stdc++.h>using namespace std;using Graph = vector<vector<int>>;
Graph G(7);vector<bool> seen;vector<int> todo;
void bfs(){ while(todo.size() > 0) { // todoからFIFOでvを取り出す int v = todo.at(0); todo.erase(todo.begin());
cout << v << ' '; for (int next_v : G.at(v)) { if (seen.at(next_v)) continue; seen.at(next_v) = true; todo.push_back(next_v); } }}
int main(){ G.at(0) = {1, 2}; G.at(1) = {0, 2, 3}; G.at(2) = {0, 1, 4}; G.at(3) = {1, 4, 5}; G.at(4) = {2, 3, 6}; G.at(5) = {3}; G.at(6) = {4};
seen.assign(7, false); seen.at(0) = true; todo.push_back(0); bfs();}結果
0 1 2 3 4 5 6DFS(深さ優先探索)
上記のBFSのコードの下記部分を変更する。
変更前(BFS)
// todoからFIFOでvを取り出すint v = todo.at(0);todo.erase(todo.begin());変更後(DFS)
// todoからLIFOでvを取り出すint v = todo.at(todo.size() - 1);todo.pop_back();サンプルコード
#include <bits/stdc++.h>using namespace std;using Graph = vector<vector<int>>;
Graph G(7);vector<bool> seen;vector<int> todo;
void dfs(){ while(todo.size() > 0) { // todoからLIFOでvを取り出す int v = todo.at(todo.size() - 1); todo.pop_back();
cout << v << ' '; for (int next_v : G.at(v)) { if (seen.at(next_v)) continue; seen.at(next_v) = true; todo.push_back(next_v); } }}
int main(){ G.at(0) = {1, 2}; G.at(1) = {0, 2, 3}; G.at(2) = {0, 1, 4}; G.at(3) = {1, 4, 5}; G.at(4) = {2, 3, 6}; G.at(5) = {3}; G.at(6) = {4};
seen.assign(7, false); seen.at(0) = true; todo.push_back(0); dfs();}結果
0 2 4 6 3 5 1DFS(再帰を使う場合)
サンプルコード
#include <bits/stdc++.h>using namespace std;using Graph = vector<vector<int>>;
void dfs(const Graph &G, vector<bool> &seen, int v){ cout << v << ' '; seen.at(v) = true; for (auto next_v : G.at(v)) { if (seen.at(next_v)) continue; dfs(G, seen, next_v); }}
int main(){ Graph G(7); G.at(0) = {1, 2}; G.at(1) = {0, 2, 3}; G.at(2) = {0, 1, 4}; G.at(3) = {1, 4, 5}; G.at(4) = {2, 3, 6}; G.at(5) = {3}; G.at(6) = {4};
vector<bool> seen(G.size(), false); dfs(G, seen, 0);}結果
0 1 2 4 3 5 6