# 題目: UVa 1112 - Mice and Maze

# 題目說明

有一張有向圖,每個點走到另一個點都會花費時間
每個點走到終點都有一條最短路徑
求有多少點能在時間限制內走到終點


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

  1. N 代表有 N 個點
  2. End 代表終點
  3. Time 代表時間限制
  4. M 代表有幾個邊

接下來有 M 行,每行有三個整數 uvw
代表 u 點及 v 點間有一條長 w 的邊


OUTPUT:
輸出能在時間限制內走到終點的點的數量

終點也算一個點

# 解題方法

如果從每個點開始走到終點,會很麻煩,所以改為從終點開始走 (存 edge 的時候反向存)
dijkstra 演算法搭配 priority_queue 建出終點到每一個點的最小路徑
最後再判斷每個點的最小路徑有沒有在時間限制內

# 參考程式碼

#include <iostream>
#include <queue>
#include <vector>
#include <memory.h>
using namespace std;
typedef pair<int, int> p;
vector< vector<p> > edge;
priority_queue<p, vector<p>, greater<p>> pq;
int vals[101];
int vis[101];
void dijkstra(int End)
{
	vals[End] = 0;
	pq.push({ 0, End });
	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;
	cin >> T;
	while (T--)
	{
		int N, End, Time, M;
		cin >> N >> End >> Time >> M;
		// init
		edge.assign(N + 1, vector<p>());
		memset(vis, false, sizeof(vis));
		for (int i = 0; i < 101; ++i) vals[i] = Time + 1;
		while (M--)
		{
			int u, v, w;
			cin >> u >> v >> w;
			edge[v].push_back({ u, w });
		}
		// dijkstra algorithm
		dijkstra(End);
		int count = 0;
		for (int i = 1; i <= N; ++i) if (vals[i] <= Time) ++count;
		cout << count << "\n";
		if (T) cout << "\n";
	}
	return 0;
}

# 參考資料

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