Sending email
Time Limit: 3 seconds
"A new internet watchdog is creating a stir in Springfield. Mr. X, if that is his real name, has come up with a sensational scoop." |
There are n SMTP servers connected by network cables. Each of the m cables connects two computers and has a certain latency measured in milliseconds required to send an email message. What is the shortest time required to send a message from server S to serverT along a sequence of cables? Assume that there is no delay incurred at any of the servers.
Input
The first line of input gives the number of cases, N. N test cases follow. Each one starts with a line containing n (2<=n<20000), m(0<=m<50000), S (0<=S<n) and T (0<=T<n). S!=T. The next m lines will each contain 3 integers: 2 different servers (in the range [0,n-1]) that are connected by a bidirectional cable and the latency, w, along this cable (0<=w<=10000).
Output
For each test case, output the line "Case #x:" followed by the number of milliseconds required to send a message from S to T. Print "unreachable" if there is no route from S to T.
Sample Input | Sample Output |
3 2 1 0 1 0 1 100 3 3 2 0 0 1 100 0 2 200 1 2 50 2 0 0 1 | Case #1: 100 Case #2: 150 Case #3: unreachable |
思路:裸的最短路。但是n有2W,所以要用优先队列优化,通过这题了解了优先队列优化的dijkstra算法和Bellman-ford算法。
代码:
优先队列优化的dijkstra:
#include <stdio.h>
#include <string.h>
#include <utility>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
const int MAXN = 20005;
const int MAXM = 100005;
typedef pair<int, int> pii;
priority_queue<pii, vector<pii>, greater<pii> >q;
int t, n, m, s, e;
int first[MAXN], a[MAXM], b[MAXM], v[MAXM], next[MAXM], vis[MAXN], d[MAXN];
void init() {
memset(first, -1, sizeof(first));
scanf("%d%d%d%d", &n, &m, &s, &e);
for (int i = 0; i < m; i ++) {
scanf("%d%d%d", &a[i], &b[i], &v[i]);
a[i + m] = b[i], b[i + m] = a[i], v[i + m] = v[i];
next[i] = first[a[i]];
first[a[i]] = i;
next[i + m] = first[a[i + m]];
first[a[i + m]] = i + m;
}
}
int dijkstra(int s) {
memset(d, INF, sizeof(d));
memset(vis, 0, sizeof(vis));
d[s] = 0;
q.push(make_pair(d[s], s));
while (!q.empty()) {
pii u = q.top(); q.pop();
int x = u.second;
if (vis[x]) continue;
vis[x] = 1;
for (int i = first[x]; i != -1; i = next[i])
if (d[b[i]] > d[x] + v[i]) {
d[b[i]] = d[x] + v[i];
q.push(make_pair(d[b[i]], b[i]));
}
}
return d[e];
}
void solve() {
init();
int ans = dijkstra(s);
if (ans == INF)
printf("unreachable\n");
else
printf("%d\n", ans);
}
int main() {
int cas = 0;
scanf("%d", &t);
while (t --) {
printf("Case #%d: ", ++ cas);
solve();
}
return 0;
}
2、Bellman-Ford
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
const int MAXN = 20005;
const int MAXM = 100005;
queue<int>q;
int t, n, m, s, e;
int first[MAXN], a[MAXM], b[MAXM], v[MAXM], next[MAXM], vis[MAXN], d[MAXN];
void init() {
memset(first, -1, sizeof(first));
scanf("%d%d%d%d", &n, &m, &s, &e);
for (int i = 1; i <= m; i ++) {
scanf("%d%d%d", &a[i], &b[i], &v[i]);
a[i + m] = b[i], b[i + m] = a[i], v[i + m] = v[i];
next[i] = first[a[i]];
first[a[i]] = i;
next[i + m] = first[a[i + m]];
first[a[i + m]] = i + m;
}
}
int SPFA(int s) {
memset(d, INF, sizeof(d));
memset(vis, 0, sizeof(vis));
d[s] = 0;
q.push(s);
while (!q.empty()) {
int u = q.front(); q.pop();
vis[u] = 0;
for (int i = first[u]; i != -1; i = next[i])
if (d[b[i]] > d[u] + v[i]) {
d[b[i]] = d[u] + v[i];
if (!vis[b[i]]) {
vis[b[i]] = 1;
q.push(b[i]);
}
}
}
return d[e];
}
void solve() {
init();
int ans = SPFA(s);
if (ans == INF)
printf("unreachable\n");
else
printf("%d\n", ans);
}
int main() {
int cas = 0;
scanf("%d", &t);
while (t --) {
printf("Case #%d: ", ++ cas);
solve();
}
return 0;
}