--- tags: CSES題解 --- CSES Problem Set — Tree Distances I 題解 === 題目 --- 給一顆有$n$個節點的樹。 找出每個節點到其他節點的最大距離。 ### 輸入 第一行輸入包含一個整數$n$ : 節點的數量。這些節點編號為$1,2,\ldots,n$。 接下來有$n-1$描述邊。每一行包含兩個整數$a$和$b$ : 點$a$和$b$間有一條邊。 ### 輸出 輸出$n$個整數 : 所有節點$1,2,\ldots,n$到其他點的最大距離。 想法 --- 根據樹直徑那題所說,每個節點的最遠點必是樹直徑的其中一端。 因此對兩個直徑端點分別``DFS``,對每個節點來說,其中一個端點會是他的最遠點,從直徑兩端``DFS``時對每個節點距離取``max``即可。 範例程式碼 --- ```cpp= #include<bits/stdc++.h> using namespace std; int cnt=1; vector<int> Head(200500,0); vector<int> Next(400500); vector<int> To(400500); vector<int> maxdis(200500,0); void addEdge(int u,int v){ Next[cnt]=Head[u]; To[cnt]=v; Head[u]=cnt++; } /*************鍊式前向星建圖****************/ int farn; int maxd=-1; //找出直徑兩端 void dfs(int u,int par,int dis){ if(dis>maxd){ maxd=dis; farn=u; } for(int e=Head[u];e;e=Next[e]){ int x=To[e]; if(x!=par){ dfs(x,u,dis+1); } } } //更新每個點的最大距離 void dfs2(int u,int par,int dis){ maxdis[u]=max(maxdis[u],dis); for(int e=Head[u];e;e=Next[e]){ int x=To[e]; if(x!=par){ dfs2(x,u,dis+1); } } } int main(){ int n; cin>>n; for(int i=0;i<n-1;i++){ int a,b; cin>>a>>b; addEdge(a,b); addEdge(b,a); } //找出直徑兩個端點 dfs(1,0,0); maxd=-1; int start=farn; dfs(farn,0,0); //從直徑兩端分別DFS dfs2(farn,0,0); dfs2(start,0,0); for(int i=1;i<=n;i++) cout<<maxdis[i]<<" \n"[i==n]; return 0; } ```