# DFS# Tree# Graph

b967 - 4. 血緣關係

🔗 前往 ZeroJudge 原題

題目描述

題目要求找出一個家族關係圖中最遠的血緣距離。家族關係圖以樹狀結構表示,其中一個節點是祖先,其他節點是其後代。血緣距離定義為兩個節點之間的路徑長度。

解題思路

這題可以使用深度優先搜尋 (DFS) 來解決。首先,我們需要建立一個鄰接表來表示家族關係圖。然後,我們從根節點 (節點 0) 開始進行 DFS,找到距離最遠的節點。接著,再次從這個最遠的節點開始進行 DFS,找到從該節點到其他節點的最長路徑,這就是最遠的血緣距離。

具體步驟如下:

  1. 建立鄰接表 E,其中 E[i] 儲存節點 i 的所有子節點。
  2. 進行第一次 DFS,從根節點 0 開始,找到距離最遠的節點,並記錄其深度 ma
  3. 使用 rt[ma] 記錄第一次 DFS 找到的最遠節點。
  4. 清空 has 陣列,然後從 rt[ma] 再次進行 DFS,找到從該節點到其他節點的最長路徑,即最遠的血緣距離。

複雜度分析

  • 時間複雜度: O(N),其中 N 是家族成員的數量。因為 DFS 遍歷了圖中的所有節點和邊。
  • 空間複雜度: O(N),主要用於儲存鄰接表 Ehas 陣列和 rt 陣列。

程式碼

#include <iostream>
#include <vector>
using namespace std;
int n,x,y,rt[100005],has[100005],ma;
vector <int> E[100005]; 
void dfs(int it,int stp){
	if(has[it])return;
	ma=max(ma,stp);
	has[it]=1;
	rt[stp]=it;
	for(int i=0;i<E[it].size();++i){
		dfs(E[it][i],stp+1);
	}
}
int main(){
	cin.tie(0); ios::sync_with_stdio(false);
	while(cin >> n){
		ma=0;
		for(int i=0;i<n;++i){
			has[i]=0;
			E[i].clear();
		}
		for(int i=0;i<n-1;++i){
			cin >> x >> y;
			E[x].push_back(y);
			E[y].push_back(x);
		}
		dfs(0,0);
		for(int i=0;i<n;++i){
			has[i]=0;
		}
		dfs(rt[ma],0);
		cout << ma << "\n";
	}
}

Discussion