# 題目: UVa 10986 - Sending email

# 題目說明

n 台 SMTP 伺服器,以 m 條網路線互相連接
當一台 SMTP 伺服器向另一台 SMTP 伺服器傳送訊息時會產生延遲
求從 s 伺服器向 v 伺服器傳送訊息的最小延遲


INPUT:
第一行有一個整數 T ,代表有 T 筆測資
每筆測資第一行有四個整數 nmst

  1. n 代表有 n 台 SMTP 伺服器
  2. m 代表有 m 條網路線
  3. s 代表起點
  4. t 代表終點

接下來有 m 行,每行有三個整數 uvw
代表 u 伺服器向 v 伺服器傳送訊息會延遲 w


OUTPUT:
輸出從 s 伺服器向 v 伺服器傳送訊息的最小延遲
如果訊息無法送達則輸出 unreachable

# 解題方法

由於是無向圖,所以要建雙向的邊
dijkstra 演算法搭配 priority_queue 建出起點到每一個點的最小延遲
輸出終點的最小延遲

# 參考程式碼

#include <iostream>
#include <queue>
#include <vector>
#include <memory.h>
using namespace std;
typedef pair<int, int> p;
priority_queue<p, vector<p>, greater<p>> pq;
vector< vector<p> > edge;
int vals[20001];
bool vis[20001];
void dijkstra(int start)
{
	vals[start] = 0;
	pq.push({ 0, start });
	while (!pq.empty())
	{
		auto [val, u] = pq.top();
		pq.pop();
		vis[u] = true;
		for (auto& [v, w] : edge[u]) if (!vis[v])
		{
			int tmp = val + w;
			if (vals[v] == -1 || vals[v] > tmp)
			{
				vals[v] = tmp;
				pq.push({ tmp, v });
			}
		}
	}
}
int main()
{
	// fast io
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int T, cases = 0;
	cin >> T;
	while (T--)
	{
		int n, m, s, t;
		cin >> n >> m >> s >> t;
		// init
		edge.assign(n, vector<p>());
		memset(vals, -1, sizeof(vals));
		memset(vis, false, sizeof(vis));
		// store data in both side
		while (m--)
		{
			int u, v, w;
			cin >> u >> v >> w;
			edge[u].push_back({ v, w });
			edge[v].push_back({ u, w });
		}
		// dijkstra algorithm
		dijkstra(s);
		cout << "Case #" << ++cases << ": ";
		if (vals[t] == -1) cout << "unreachable\n";
		else cout << vals[t] << "\n";
	}
	return 0;
}

# 參考資料

https://www.larrysprognotes.com/UVa%20-%2010986/