#include <iostream> #include <vector> #include <queue> #include <unordered_set> #include <memory>
using namespace std;
class Node { public: int row, col, F, H, G; shared_ptr<Node> prev; Node(int _row, int _col) : row(_row), col(_col), F(0), H(0), G(0), prev(nullptr) {}
Node(int _row, int _col, int _G, int _H, shared_ptr<Node> _prev) : row(_row), col(_col), G(_G), H(_H), prev(_prev) { F = G + H; }
bool operator==(const Node &other) const { return row == other.row && col == other.col; } };
struct NodeHash { size_t operator()(const shared_ptr<Node> &node) const { return hash<int>()(node->row) ^ hash<int>()(node->col); } };
struct cmp { bool operator()(shared_ptr<Node> a, shared_ptr<Node> b) { return a->F > b->F; } };
int calculate_H(int cur_row, int cur_col, int end_row, int end_col) { return abs(end_row - cur_row) + abs(end_col - cur_col); }
bool inCloseList(unordered_set<shared_ptr<Node>, NodeHash> &close_list, shared_ptr<Node> node) { return close_list.find(node) != close_list.end(); }
int main() { vector<vector<int>> Graph = {{0, 0, 0, 0, 0}, {0, 0, 1, 0, 0}, {0, 0, 1, 0, 0}, {0, 0, 1, 0, 0}, {0, 0, 0, 0, 0}}; int m = Graph.size(); int n = Graph[0].size(); auto end = make_shared<Node>(2, 4); auto start = make_shared<Node>(2, 0, 0, calculate_H(2, 0, end->row, end->col), nullptr);
priority_queue<shared_ptr<Node>, vector<shared_ptr<Node>>, cmp> open_list; unordered_set<shared_ptr<Node>, NodeHash> close_set; unordered_set<shared_ptr<Node>, NodeHash> open_set; open_list.push(start); open_set.insert(start); vector<pair<int, int>> neighbors = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {1, 1}, {-1, 1}, {1, -1}}; while (!open_list.empty()) { auto cur = open_list.top();
for (auto &neighbor: neighbors) { int new_row = cur->row + neighbor.first; int new_col = cur->col + neighbor.second; if (new_row < 0 || new_row >= m || new_col < 0 || new_col >= n || Graph[new_row][new_col] == 1) { continue; } auto new_node = make_shared<Node>(new_row, new_col, cur->G + (neighbor.first == 0 || neighbor.second == 0 ? 10 : 14), calculate_H(new_row, new_col, end->row, end->col), cur); if (inCloseList(close_set, new_node)) { continue; } if (new_row == end->row && new_col == end->col) { auto temp = new_node; while (temp != nullptr) { cout << "(" << temp->row << ", " << temp->col << ")" << endl; temp = temp->prev; } return 0; } auto it = open_set.find(new_node); if (it == open_set.end()) { open_list.push(new_node); open_set.insert(new_node); } else { auto old_node = *it; if (new_node->G < old_node->G) { old_node->G = new_node->G; old_node->F = old_node->G + old_node->H; old_node->prev = cur; } } } open_list.pop(); open_set.erase(cur); close_set.insert(cur); } return 0; }
|