題目:
Problem E
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."Kent Brockman
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 server T 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 toT. 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
Problemsetter: Igor Naverniouk
題目大意:
給一個圖, 求從s點到t點的最小距離。
分析與總結:
赤裸裸的最短路,但n太大顯然是不能用鄰接矩陣的,需要用鄰接表+優先隊列優化。
代碼:
1. Dijkstra, 0.148s
[cpp]
#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
using namespace std;
typedef pair<int,int>pii;
priority_queue<pii,vector<pii>,greater<pii> >q;
const int N = 100005;
const int INF = 1000000000;
int n, m, beg, end, k;
int head[N], next[N], u[N], v[N], w[N], d[N];
bool vis[N];
inline void read_graph(){
scanf("%d%d%d%d",&n,&m,&beg,&end);
memset(head, -1, sizeof(head));
for(int e=1; e<=m; ++e){
scanf("%d%d%d",&u[e],&v[e],&w[e]);
u[e+m]=v[e], v[e+m]=u[e], w[e+m]=w[e];
next[e] = head[u[e]];
head[u[e]] = e;
next[e+m] = head[u[e+m]];
head[u[e+m]] = e+m;
}
}
inline void Dijkstra(int src){
memset(vis, 0, sizeof(vis));
for(int i=0; i<n; ++i) d[i] = INF;
d[src] = 0;
q.push(make_pair(d[src], src));
while(!q.empty()){
pii u = q.top(); q.pop();
int x = u.second;
if(vis[x]) continue;
vis[x] = true;
for(int e=head[x]; e!=-1; e=next[e])if(d[v[e]] > d[x]+w[e]){
d[v[e]] = d[x]+w[e];
q.push(make_pair(d[v[e]], v[e]));
}
}
}
int main(){
int T,cas=1;
scanf("%d",&T);
while(T--){
read_graph();
Dijkstra(beg);
printf("Case #%d: ",cas++);
if(d[end]!=INF) printf("%d\n", d[end]);
else puts("unreachable");
}
return 0;
}
2.SPFA, 0.160s
[cpp]
#include<cstdio>
#include<cstring>
#include<utility>
#include<queue>
using namespace std;
queue<int>q;
const int N = 100005;
const int INF = 1000000000;
int n, m, beg, end, k;
int head[N], next[N], u[N], v[N], w[N], d[N];
bool vis[N];
inline void read_graph(){
scanf("%d%d%d%d",&n,&m,&beg,&end);
memset(head, -1, sizeof(head));
for(int e=1; e<=m; ++e){
scanf("%d%d%d",&u[e],&v[e],&w[e]);
u[e+m]=v[e], v[e+m]=u[e], w[e+m]=w[e];
next[e] = head[u[e]];
head[u[e]] = e;
next[e+m] = head[u[e+m]];
head[u[e+m]] = e+m;
}
}
inline void SPFA(int src){
memset(vis, 0, sizeof(vis));
for(int i=0; i<n; ++i) d[i] = INF;
d[src] = 0;
q.push(src);
while(!q.empty()){
int u = q.front(); q.pop();
vis[u] = false;
for(int e=head[u]; e!=-1; e=next[e])if(d[v[e]] > d[u]+w[e]){
d[v[e]] = d[u] + w[e];
if(!vis[v[e]]){
vis[v[e]] = true;
q.push(v[e]);
}
}
}
}
int main(){
int T,cas=1;
scanf("%d",&T);
while(T--){
read_graph();
SPFA(beg);
printf("Case #%d: ",cas++);
if(d[end]!=INF) printf("%d\n", d[end]);
else puts("unreachable");
}
return 0;
}