4. 血緣關係
解題
這題是一個很明顯的圖論題目,那我們先使用講解資料結構:
- parent:所有節點的父節點,如果這個節點是root的話,就是-1
- child:所有節點的子節點,若這個子節點的child長度為0,這個節點則為leaf
- leaf:遍歷過child之後找到的leaf,以便進行樹狀結構運算(BFS)
- children:紀錄每個節點child的數量,以便運算是否可以進入queue進行BFS運算
- h:所有的節點高度
這題有個想法,當你一個節點下的子節點只有一個,那你就是這個節點的距離子節點+1,如果你節點下的子節點有兩個或以上,那就是取最長的兩個+2,這是尋找最長節點距離的方法
solve函數是在進行BFS運算,當queue的開頭為root代表所有的節點已經遍歷完成,如果沒有,那就把q繼續pop,如果這個節點下的子節點已經都被檢查過了($children_i=0$),那我們就把這個節點加入BFS運算
AC Code
python
from sys import stdin
from collections import deque
import copy
n=int(stdin.readline().strip())
parent=[-1]*n
child=[[] for _ in range(n)]
for _ in range(n-1):
a,b=map(int,stdin.readline().strip().split())
parent[b]=a
child[a].append(b)
children=[len(child[i]) for i in range(n)]
# 尋找葉子
leaf=[]
for i in range(len(child)):
if len(child[i])==0:
leaf.append(i)
def solve(children):
q=deque(leaf)
h=[0]*n
while parent[q[0]]!=-1:
x=q.popleft()
children[parent[x]]-=1
if children[parent[x]]==0:
q.append(parent[x])
h[parent[x]]=max(h[parent[x]],h[x]+1)
return h
def main(h):
max_num=0
for i in range(len(child)):
if len(child[i])==1:
max_num=max(max_num,h[child[i][0]]+1)
elif len(child[i])>=2:
temp=[]
for j in child[i]:
temp.append(h[j])
temp.sort()
max_num=max(max_num,temp[-1]+temp[-2]+2)
return max_num
print(main(solve(children)))
C++
#include<bits/stdc++.h>
using namespace std;
vector<int> solve(int n,const vector<int>& parent,vector<int>& children,const vector<int>& leaf){
queue<int> q;
for(int l : leaf){
q.push(l);
}
vector<int> h(n,0);
while(parent[q.front()]!=-1){
int x=q.front();
q.pop();
int p=parent[x];
if(p!=-1){
h[p]=max(h[p],h[x]+1);
children[p]--;
if(children[p]==0){
q.push(p);
}
}
}
return h;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
vector<int> parent(n,-1);
vector<vector<int>> child(n);
vector<int> children(n,0);
for(int i=0;i<n-1;i++){
int a,b;
cin>>a>>b;
parent[b]=a;
child[a].push_back(b);
children[a]++;
}
vector<int> leaf;
for(int i=0;i<n;i++){
if(child[i].empty()){
leaf.push_back(i);
}
}
vector<int> h=solve(n,parent,children,leaf);
int max_num=0;
for(int i=0;i<n;i++){
if(child[i].size()==1){
max_num=max(max_num,h[child[i][0]]+1);
}else if(child[i].size()>=2){
vector<int> temp;
for(int c:child[i]){
temp.push_back(h[c]);
}
sort(temp.begin(),temp.end());
int m=temp.size();
max_num=max(max_num,temp[m-1]+temp[m-2]+2);
}
}
cout<<max_num<<endl;
return 0;
}