UVA 10986 - Sending email

UVA 10986 - Sending email

LAVI

解題觀念

Dijkstra

可以參考我的課程簡報:MST & Shortest Path
關於 Dijkstra 的基本觀念可以參考我的這篇文章:Algorithm - Dijkstra

題目敘述

電腦線路最小延遲計算
有 N 台伺服器,以 M 條線路彼此連接
當一台伺服器向另一台伺服器傳送訊息時會因線路產生延遲
請找出能以最小延遲從起點伺服器 S 向終點伺服器 T 傳送訊息的線路走法

Input

第一行為 t 代表有多少組測資

每筆測資中
第一行有四個整數 分別為 N、M、S、T
N 代表有多少台伺服器
M 代表有多少條線路
S 代表起點伺服器
T 代表終點伺服器

接下來 M 行有三個數 u、v、w 表示線段兩端連接的伺服器及線路延遲量

1
2
3
4
5
6
7
8
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

Output

輸出從伺服器 S 到伺服器 T 傳送訊息的最小延遲
如果無法送達,則輸出 unreachable

輸出格式為:
”Case #<當前為第幾筆測資>:”
間隔一個空白後輸出最小延遲量/unreachable

1
2
3
Case #1: 100
Case #2: 150
Case #3: unreachable

Solution Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include<bits/stdc++.h>
using namespace std;

const int maxn = 50000+5;
const int INF = 0x3f3f3f3f;

struct Edge{
int v, w;
};

struct Item{
int u, dis;

// 取路徑最短
bool operator < (const Item &rhs) const{
return dis > rhs.dis;
}
};

vector<Edge> G[maxn];
int dist[maxn];

void Dijkstra(int S){
memset(dist, INF, sizeof(dist));
dist[S] = 0;

priority_queue<Item> pq;
pq.push({S, 0});

while(!pq.empty()){
Item now = pq.top();
pq.pop();

// 如果當前走到這個點的路徑比原本走到此點的路徑還長 就不再考慮
if(now.dis > dist[now.u]) continue;

// 鬆弛更新
// 如果有與當前的點相連之點可更新為更短路徑 則將他推入佇列
// 讓該點被取出時確認他是否能更新其他與該點相連的點的最短路徑
for(Edge e : G[now.u]){
if(dist[e.v] > dist[now.u] + e.w){
dist[e.v] = dist[now.u] + e.w;
pq.push({e.v, dist[e.v]});
}
}
}
}

int main(){
int t, Case = 1;
cin >> t;

while(t--){
int N, M, S, T;
cin >> N >> M >> S >> T;

for(int i = 0; i <= N; ++i) G[i].clear();

int u, v, w;
for(int i = 0; i < M; ++i){
cin >> u >> v >> w;

// 無向圖 所以兩個方向都要推
G[u].push_back({v, w});
G[v].push_back({u, w});
}

Dijkstra(S);

cout << "Case #" << Case++ << ": ";
if(dist[T] == INF) cout << "unreachable" << endl;
else cout << dist[T] << endl;
}
}
On this page
UVA 10986 - Sending email