# BFS# Priority Queue# Graph

c246 - 逃亡

🔗 前往 ZeroJudge 原題

題目描述

題目描述一個圖,其中節點代表房間,邊代表房間之間的通道,邊的權重代表通過通道所需的時間。給定一個起始房間(安全房間)和一個時間限制,要求計算在時間限制內能夠到達安全房間的房間數量。

解題思路

本題可以使用廣度優先搜尋 (BFS) 演算法來解決。由於題目要求在時間限制內到達安全房間,因此可以使用優先佇列 (Priority Queue) 來儲存待訪問的房間,優先訪問距離起始房間更近的房間。 程式碼中,dp[i] 儲存從起始房間到達房間 i 所需的最短時間。 程式碼首先讀取輸入資料,建立圖的鄰接表 e。然後,使用優先佇列 q 從起始房間開始進行 BFS。在每次迭代中,從優先佇列中取出距離起始房間最近的房間,如果到達該房間所需的時間小於或等於時間限制 t,則更新 dp[i] 的值,並將與該房間相鄰的房間加入優先佇列。 最後,統計在時間限制內能夠到達安全房間的房間數量。

複雜度分析

  • 時間複雜度: O(M log N),其中 N 是房間的數量,M 是邊的數量。這是因為 BFS 演算法需要遍歷所有邊,並且優先佇列的插入和刪除操作需要 O(log N) 的時間。
  • 空間複雜度: O(N + M),其中 N 是房間的數量,M 是邊的數量。這是因為需要儲存鄰接表和 dp 陣列。

程式碼

#include <bits/stdc++.h>
using namespace std;
int n,m,s,t,ca,dp[105],x,y,v;
int main(){
	cin >> ca;
	while(ca--){
		cin >> n >> s >> t >> m;
		priority_queue <pair <int,int>,vector  <pair <int,int>>,greater <pair <int,int>>> q;//t it
		vector <pair <int,int>> e[n+1];
		memset(dp,0x3f,sizeof(dp));
		q.push({0,s});
		for(int i=0;i<m;++i){
			cin >> x >> y >> v;
			e[y].push_back({x,v});
		}
		while(!q.empty()){
			pair <int,int> tp=q.top();
			int ti=tp.first,it=tp.second;
			q.pop();
			if(ti>t||dp[it]<=ti)continue;
			dp[it]=ti;
			for(int i=0;i<e[it].size();++i){
				q.push({ti+e[it][i].second,e[it][i].first});
			}
		}
		int ans=0;
		for(int i=1;i<=n;++i){
			if(dp[i]<=t)++ans;
		}
		cout << ans << "\n\n";
	}
}

Discussion