UVa 10986 : Sending Email

Servers 互相用雙向電纜連接,求從指定開始 Server 到指定結束 Server 的最短路徑長

測資
Input :

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 :

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


解法

因為沒有負權重的邊,因此使用 Dijkstra Algorithm
並用 Adjacent List 和 Priority Queue 來實作


完整程式碼

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <vector>
#include <list>
#include <queue>

using namespace std;

template<typename T>
using Matrix = vector<list<T>>;

constexpr int INF = 100000;


struct Edge
{
int idx;
int weight;

Edge(int i = -1, int w = INF) : idx{ i }, weight{ w } {}
};

// 由於 c++ 的 priority queue 是 max priority queue,所以要相反比較
inline bool operator<(const Edge &lhs, const Edge &rhs)
{
return lhs.weight > rhs.weight;
}


class Solution
{
public:
Solution()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}

int calculate(const Matrix<Edge> &w, const int Vertices, const int start, const int end)
{
initialize(Vertices);

priority_queue<Edge> que;

int min_idx = start;

dist[min_idx] = 0;

que.push({ min_idx,0 });

while (true)
{
min_idx = get_min_edge(que);

if (min_idx == end || min_idx == -1)
break;

checked[min_idx] = true;

relax(w, min_idx, que);
}

return dist[end];
}

private:
vector<int> dist;
vector<bool> checked;

void initialize(const int Vertices)
{
dist.clear();
checked.clear();

dist.resize(Vertices, INF);
checked.resize(Vertices, false);
}

int get_min_edge(priority_queue<Edge> &que) const
{
int min_idx = -1;

// get the min distance
while (!que.empty() && checked[min_idx = que.top().idx])
que.pop();

return min_idx;
}

void relax(const Matrix<Edge> &w, const int pivot, priority_queue<Edge> &que)
{
int d;

// out.weight
// pivot ------------------> out.idx

for (auto &out : w[pivot])
{
if (!checked[out.idx] && (d = dist[pivot] + out.weight) < dist[out.idx])
{
dist[out.idx] = d;
que.push({ out.idx,d });
}
}
}
};

int main(void)
{
int total_cases;
int vertices, edges;
int start, end;
int ans;

Solution s;
Matrix<Edge> w(20000);

int t = 0;
int a, b, v;

cin >> total_cases;


while (t++ < total_cases)
{
cin >> vertices >> edges >> start >> end;

w.clear();
w.resize(vertices);

while (edges--)
{
cin >> a >> b >> v;

// 雙向
w[a].push_back({ b,v });
w[b].push_back({ a,v });
}

ans = s.calculate(w, vertices, start, end);

cout << "Case #" << t << ": ";
if (ans >= INF)
cout << "unreachable" << endl;
else
cout << ans << endl;
}

return 0;
}
0%