——by A Code Rabbit
Description
几个服务器间发信息。
输入从某个服务器发信息到某个服务器需要的时间,和信息出发点的目的地。
输出从某台服务器发送到另外某台服务器需要的最短时间。
Type
Graph Algorithms
Analysis
明显可以构成有向图。
构图后用Dijkstra求单源最短路径即可。
由于边数远小于点数的平方,属于稀疏图,因此最好用单调队列优化的Dijkstra来做。
Solution
// UVaOJ 10986
// Sending email
// by A Code Rabbit
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXV = 20002;
const int MAXE = 50002 * 2;
const int INF = 2147483647;
template <typename T>
struct Edge {
int v;
T w;
int next;
};
template <typename T>
struct Graph {
Edge<T> edge[MAXE];
int tot_edge;
int head[MAXV];
void Init() {
tot_edge = 0;
memset(head, -1, sizeof(head));
}
void AddEdge(int u, int v, T w) {
edge[tot_edge].v = v;
edge[tot_edge].w = w;
edge[tot_edge].next = head[u];
head[u] = tot_edge;
tot_edge++;
}
};
namespace Dijkstra {
bool vis[MAXV];
template <typename T>
void Go(T d[MAXV], Graph<T> g, int n, int s) {
typedef pair<T, int> Node;
priority_queue<Node, vector<Node>, greater<Node> > pq;
memset(vis, false, sizeof(vis));
for (int i = 0; i < n; i++) { d[i] = i == s ? 0 : INF; }
pq.push(make_pair(d[s], s));
while (!pq.empty()) {
Node m = pq.top();
pq.pop();
int u = m.second;
if (vis[u]) continue;
vis[u] = true;
for (int e = g.head[u]; e != -1; e = g.edge[e].next) {
int v = g.edge[e].v; int w = g.edge[e].w;
if (d[u] + w < d[v]) {
d[v] = d[u] + w;
pq.push(make_pair(d[v], v));
}
}
}
}
};
int n, m, s, t;
Graph<int> graph;
int dis[MAXV];
int main() {
int tot_case;
scanf("%d", &tot_case);
for (int num_case = 0; num_case < tot_case; num_case++) {
// Input.
scanf("%d%d%d%d", &n, &m, &s, &t);
graph.Init();
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
graph.AddEdge(u, v, w);
graph.AddEdge(v, u, w);
};
// Solve.
Dijkstra::Go(dis, graph, n, s);
// Output.
printf("Case #%d: ", num_case + 1);
if (dis[t] == INF) printf("unreachable\n");
else printf("%d\n", dis[t]);
}
return 0;
}