最短路算法模板
最短路算法有很多種,包括Dijkstra算法、Bellman-Ford算法、A*算法等。這裡提供一個Dijkstra算法的模板,用於在有向圖中找到從一個頂點到其他所有頂點的最短路徑。
#include <vector>
#include <queue>
#include <utility>
#include <unordered_set>
#include <unordered_map>
#include <iostream>
struct Graph {
std::vector<std::vector<int>> adjList;
int V; // 頂點數
Graph(int V) : V(V) {
adjList.resize(V);
}
void addEdge(int src, int dest, int weight) {
adjList[src].push_back({dest, weight});
}
};
struct Edge {
int dest;
int weight;
};
struct Compare {
bool operator()(const Edge& a, const Edge& b) const {
return a.weight > b.weight;
}
};
class DisjointSet {
public:
DisjointSet(int n) : parent(n, -1), rank(n) {}
int find(int i) {
if (parent[i] < 0)
return i;
else
return parent[i] = find(parent[i]);
}
void unionSet(int x, int y) {
int xRoot = find(x);
int yRoot = find(y);
if (xRoot == yRoot)
return;
if (rank[xRoot] < rank[yRoot]) {
parent[xRoot] = yRoot;
} else if (rank[yRoot] < rank[xRoot]) {
parent[yRoot] = xRoot;
} else {
parent[yRoot] = xRoot;
rank[xRoot]++;
}
}
private:
std::vector<int> parent;
std::vector<int> rank;
};
class PriorityQueue {
public:
PriorityQueue(int capacity) : maxSize(capacity), size(0) {
pq.resize(capacity);
}
void push(const Edge& e) {
pq[size++] = e;
if (size > maxSize / 2) {
std::make_heap(pq.begin(), pq.begin() + size, Compare());
}
}
Edge pop() {
if (size == 0)
return Edge();
std::pop_heap(pq.begin(), pq.begin() + size, Compare());
Edge res = pq[size - 1];
pq.pop_back();
size--;
return res;
}
private:
const int maxSize;
int size;
std::vector<Edge> pq;
};
void dijkstra(Graph& graph, int src) {
std::vector<int> dist(graph.V, INT_MAX);
std::vector<bool> visited(graph.V, false);
dist[src] = 0;
PriorityQueue pq(graph.V);
pq.push({src, 0});
while (!pq.empty()) {
Edge edge = pq.pop();
int u = edge.dest;
if (dist[u] != INT_MAX)
continue;
visited[u] = true;
for (auto& neighbor : graph.adjList[u]) {
int v = neighbor.dest;
int weight = neighbor.weight;
if (dist[v] > dist[u] + weight) {
dist[v] = dist[u] + weight;
pq.push({v, dist[v]});
}
}
}
for (int i = 0; i < graph.V; i++) {
std::cout << dist[i] << " ";
}
std::cout << std::endl;
}
int main() {
int V, E;
std::cin >> V >> E;
Graph graph(V);
for (int i = 0; i < E; i++) {
int src, dest, weight;
std::cin >> src >> dest >> weight;
graph.addEdge(src - 1, dest - 1, weight);
}
dijkstra(graph, 0);
return 0;
}
這個模板使用了一個優先佇列來維護一個最小堆,用於存儲未訪問的頂點及其距離。它還使用了一個DisjointSet數據結構來維護併查集,用於判斷兩個頂點是否在同一連通分量中。在實際套用中,你可能需要根據具體問題調整算法和數據結構。