https://hihocoder.com/problemset/problem/1093
实现参考了算法导论。
#include <bits/stdc++.h>
#define DBG(x) cerr << #x << " = " << x << endl
using namespace std;
typedef long long LL;
const int MAX_N = 100000 + 16;
const int MAX_M = 1000000 + 16;
const int INF = 0x3F3F3F3F;
struct Edge {
int u, v, c;
Edge() {}
Edge(int u, int v, int c) : u(u), v(v), c(c) {}
};
struct Graph {
vector<int> g[MAX_N];
vector<Edge> edges;
int n;
void init(int n) {
this->n = n;
for (int i = 0; i <= n; i++)
g[i].clear();
edges.clear();
}
void add(int u, int v, int c) {
edges.push_back(Edge(u, v, c));
g[u].push_back(edges.size() - 1);
}
} graph;
struct BellmanFord {
int dist[MAX_N];
void init(int n, int s) {
for (int i = 0; i <= n; i++)
dist[i] = INF;
dist[s] = 0;
}
void work(const Graph &g, int s) {
init(g.n, s);
for (int i = 1; i < g.n; i++) {
for (const Edge &e : g.edges) {
dist[e.v] = min(dist[e.v], dist[e.u] + e.c);
}
}
}
} bellman_ford;
struct Dijkstra {
int dist[MAX_N];
bool vis[MAX_N];
void init(int n, int s) {
for (int i = 0; i <= n; i++) {
dist[i] = INF;
vis[i] = false;
}
dist[s] = 0;
}
int extract_min(int n) {
int d = INF;
int u = 0;
for (int i = 1; i <= n; i++) {
if (!vis[i] && dist[i] < d) {
d = dist[i];
u = i;
}
}
return u;
}
void work(const Graph &g, int s) {
init(g.n, s);
int left = g.n;
while (left--) {
int u = extract_min(g.n);
vis[u] = true;
for (int i = 0; i < g.g[u].size(); i++) {
const Edge &e = g.edges[g.g[u][i]];
dist[e.v] = min(dist[e.v], dist[e.u] + e.c);
}
}
}
} dijkstra;
struct DijkstraPremium {
struct Node {
int u, d;
Node() {}
Node(int u, int d) : u(u), d(d) {}
bool operator>(const Node &rhs) const {
return this->d > rhs.d;
}
};
int dist[MAX_N];
bool vis[MAX_N];
priority_queue<Node, vector<Node>, greater<Node>> pq;
void init(int n, int s) {
for (int i = 0; i <= n; i++) {
dist[i] = INF;
vis[i] = false;
}
dist[s] = 0;
while (!pq.empty())
pq.pop();
pq.push(Node(s, dist[s]));
}
void work(const Graph &g, int s) {
init(g.n, s);
while (!pq.empty()) {
Node node = pq.top();
pq.pop();
int u = node.u;
if (vis[u])
continue;
vis[u] = true;
for (int i = 0; i < g.g[u].size(); i++) {
const Edge &e = g.edges[g.g[u][i]];
dist[e.v] = min(dist[e.v], dist[e.u] + e.c);
pq.push(Node(e.v, dist[e.v]));
}
}
}
} dijkstra_premium;
int main(int argc, char **argv) {
int n, m, s, t;
while (scanf("%d%d%d%d", &n, &m, &s, &t) != EOF) {
graph.init(n);
for (int i = 0; i < m; i++) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
graph.add(u, v, c);
graph.add(v, u, c);
}
dijkstra_premium.work(graph, s);
printf("%d
", dijkstra_premium.dist[t]);
}
return 0;
}