#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
const unsigned N = 5;
class Node {
public:
Node(unsigned vertex) {
path.push_back(vertex);
}
Node(const Node &src, unsigned vertex, unsigned newCost) {
path = src.getPath();
path.push_back(vertex);
cost = newCost;
}
friend bool operator<(const Node &a, const Node &b) {
return a.getCost() > b.getCost();
}
vector<unsigned> getPath() const {
return path;
}
unsigned getCost() const {
return cost;
}
vector<unsigned> getAvailableNextVertexes() const {
vector<unsigned> vertexes;
for (unsigned i = 0; i < N; ++i) {
if (find(path.begin(), path.end(), i) == path.end()) {
vertexes.push_back(i);
}
}
return vertexes;
}
unsigned getLastVertex() const {
return path.back();
}
private:
unsigned cost = 0;
vector<unsigned> path{};
};
void solute(vector<vector<unsigned>> &matrix) {
priority_queue<Node> state;
unsigned currentOptimizedCost = INT_MAX;
vector<Node> currentOptimizedPaths{};
state.push(Node(0));
while (!state.empty()) {
Node currentNode = state.top();
state.pop();
auto availableVertexes = currentNode.getAvailableNextVertexes();
if (availableVertexes.size() == 1) {
unsigned vertex = availableVertexes[0];
unsigned lastVertex = currentNode.getLastVertex();
unsigned tempCost = currentNode.getCost() + matrix[lastVertex][vertex];
Node tempNode(currentNode, vertex, tempCost);
if (tempCost < currentOptimizedCost) {
unsigned tempCompleteCost = tempCost + matrix[vertex][0];
Node currentCompleteNode(tempNode, 0, tempCompleteCost);
if (tempCompleteCost < currentOptimizedCost) {
currentOptimizedCost = tempCompleteCost;
currentOptimizedPaths = {currentCompleteNode};
} else if (tempCompleteCost == currentOptimizedCost) {
currentOptimizedPaths.push_back(currentCompleteNode);
}
}
} else {
for (unsigned vertex : availableVertexes) {
unsigned lastVertex = currentNode.getLastVertex();
unsigned tempCost = currentNode.getCost() + matrix[lastVertex][vertex];
if (tempCost > currentOptimizedCost) {
continue;
}
Node tempNode(currentNode, vertex, tempCost);
state.push(tempNode);
}
}
}
cout << "最优值: " << currentOptimizedCost << endl;
for (const Node &node : currentOptimizedPaths) {
const vector<unsigned> &path = node.getPath();
cout << path[0] + 1;
for (int i = 1; i < path.size(); i++) {
cout << "--" << path[i] + 1;
}
cout << endl;
}
}
int main() {
vector<vector<unsigned>> matrix{
{0, 20, 30, 10, 11},
{20, 0, 16, 4, 2},
{30, 16, 0, 6, 7},
{10, 4, 6, 0, 12},
{11, 2, 7, 12, 0},
};
solute(matrix);
}