# DFS# Graph# Cycle Detection

d536 - 3. 圖形迴圈偵錯問題

🔗 前往 ZeroJudge 原題

題目描述

題目要求判斷一個有向圖中是否存在迴圈,如果存在,則輸出最短迴圈的連結數。如果不存在迴圈,則輸出 0。圖形由連結表示,連結由兩個大寫字母組成,表示從第一個字母對應的節點到第二個字母對應的節點存在單向邊。

解題思路

使用深度優先搜尋 (DFS) 來遍歷圖形。在 DFS 的過程中,使用 used 陣列記錄當前節點是否已被訪問。如果 DFS 過程中再次遇到已被訪問的節點,則說明存在迴圈。在找到迴圈時,記錄迴圈的長度,並更新最短迴圈的長度。遍歷所有節點作為起點,以確保找到的是最短迴圈。

複雜度分析

  • 時間複雜度: O(V + E),其中 V 是節點數,E 是邊數。因為 DFS 最多會遍歷所有節點和邊。
  • 空間複雜度: O(V),主要用於 used 陣列和 DFS 的遞迴堆疊。

程式碼

#include <iostream>
using namespace std;
int n,e[55][55],ans=55,used[55];
string s;
void dfs(int p,int step){
	if(step>=ans)return;
	//cout << p << " " << step << "\n";
	if(used[p]){
		ans=step;
		return;
	}
	used[p]=1;
	for(int i=0;i<55;++i){
		if(e[p][i]){
			dfs(i,step+1);
		}
	}
	used[p]=0;
}
int main(){
	cin >> n;
	for(int i=0;i<n;++i){
		cin >> s;
		e[s[0]-'A'][s[1]-'A']=1; 
	}
	for(int i=0;i<55;++i){
		dfs(i,0);
	}
	if(ans!=55){
		cout << ans;
	}
	else{
		cout << "0";
	}
}

Discussion