# DFS# Graph# Connectivity

b343 - 11518 - Dominos 2

🔗 前往 ZeroJudge 原題

題目描述

題目描述了骨牌倒塌的現象。給定骨牌的數量 n,骨牌之間的推倒關係 m,以及手動推倒的骨牌 l,要求計算最終倒下的骨牌總數。

解題思路

這題可以建模成一個有向圖,其中骨牌是節點,如果骨牌 x 倒下會推倒骨牌 y,則從 xy 建立一條有向邊。然後,對於每個手動推倒的骨牌,執行深度優先搜尋 (DFS) 來遍歷所有可以被推倒的骨牌。使用一個 has 陣列來記錄已經訪問過的節點,避免重複計算。

複雜度分析

  • 時間複雜度: O(n + m + l) 最壞情況下,DFS 需要遍歷所有節點和邊,且需要對每個手動推倒的骨牌執行一次 DFS。
  • 空間複雜度: O(n) e 陣列儲存圖的鄰接表,has 陣列用於記錄訪問過的節點,空間複雜度都與節點數量 n 成正比。

程式碼

#include <bits/stdc++.h>
using namespace std;
int n,m,l,ans,t,x,y;
vector <int> e[10005];
bool has[10005];
void dfs(int x){
	if(has[x])return;
	has[x]=1;
	++ans;
	for(int i=0;i<e[x].size();++i){
		dfs(e[x][i]);
	}
}
int main(){
	cin.tie(0); ios::sync_with_stdio(0);
	cin >> t;
	for(int ca=1;ca<=t;++ca){
		cin >> n >> m >> l;
		ans=0;
		memset(e,0,sizeof(e));
		memset(has,0,sizeof(has));
		for(int i=0;i<m;++i){
			cin >> x >> y;
			e[x].push_back(y);
		}
		for(int i=0;i<l;++i){
			cin >> x;
			dfs(x);
		}
		cout << ans << "\n";
	}
}

Discussion