題目:
魔法王國一共有n個城市,編號為0~n-1號,n個城市之間的道路連線起來恰好構成一棵樹。
小易現在在0號城市,每次行動小易會從當前所在的城市走到與其相鄰的乙個城市,小易最多能行動l次。
如果小易到達過某個城市就視為小易遊歷過這個城市了,小易現在要制定好的旅遊計畫使他能遊歷最多的城市,請你幫他計算一下他最多能遊歷過多少個城市(注意0號城市已經遊歷了,遊歷過的城市不重複計算)。
輸入描述:
輸入包括兩行,第一行包括兩個正整數n(2 ≤ n ≤ 50)和l(1 ≤ l ≤ 100),表示城市個數和小易能行動的次數。
第二行包括n-1個整數parent[i](0 ≤ parent[i] ≤ i), 對於每個合法的i(0 ≤ i ≤ n - 2),在(i+1)號城市和parent[i]間有一條道路連線。
輸出描述:
輸出乙個整數,表示小易最多能遊歷的城市數量。
輸入例子1:
5 2
0 1 2 3
輸出例子1:
3程式:
#include
#include
#include
#include
using
namespace
std;
int main()
}if (res < l + 1)
else
}else
}return
0;}
點評:
結構為二叉樹,求深度
畫個圖可以知道,可把 parent[i] 當作 (i+1) 的父親節點(因為 parent[i] 是可以重複的)。之前看漏了 parent[i] 的範圍限制了父節點標號比子節點小 這個條件,我用了 鏈式前向星 來建圖。
建好圖之後,就可以從樹根擴散出每個節點所在最長樹鏈的長度,選出最長的一條樹鏈,記其長度為 maxlen 。
分類討論:
若 l ≤ maxlen ,顯而易見得結果;
若 l > maxlen ,意味著可以往回走,要知道越短的樹鏈往回走的代價越低。如果從末端往回走,消耗的代價非常高,最壞情況是較短的樹鏈都連線在最遠的樹根上,整條最長鏈都要回走;如果已經知道最終步數會有剩餘,則可以先消耗富餘的步數走短鏈,最後才走最長鏈;
繼續對 rest = l - maxlen 進行討論:
若樹鏈上存在某個節點擁有另一條子鏈,其長度 x 必定小於或等於該祖先到原鏈末端的長度,考察樹鏈上每個節點到葉子的一條最短子鏈:
當 x > rest/2 可以在中途預先用掉 rest 步而不影響要走的 maxlen 最長鏈,可達城市增加 rest/2 個;
當 x ≤ rest/2 可以在中途預先用掉 2x 步而不影響要走的 maxlen 最長鏈,可達城市增加 x 個;
若所有的 x 總和 sum(x) ≤ rest/2 說明富餘的步數足夠把最短鏈到次最長鏈都走一遍,可達城市為全部 n 個。
本小節討論可知 rest/2 決定了能多走的城市數量,總共能走 min(n, 1 + rest/2 + maxlen) 個城市。
網易 遊歷魔法王國
魔法王國一共有n個城市,編號為0 n 1號,n個城市之間的道路連線起來恰好構成一棵樹。小易現在在0號城市,每次行動小易會從當前所在的城市走到與其相鄰的乙個城市,小易最多能行動l次。如果小易到達過某個城市就視為小易遊歷過這個城市了,小易現在要制定好的旅遊計畫使他能遊歷最多的城市,請你幫他計算一下他最多...
遊歷魔法王國(網易)
時間限制 1秒 空間限制 32768k 魔法王國一共有n個城市,編號為0 n 1號,n個城市之間的道路連線起來恰好構成一棵樹。小易現在在0號城市,每次行動小易會從當前所在的城市走到與其相鄰的乙個城市,小易最多能行動l次。如果小易到達過某個城市就視為小易遊歷過這個城市了,小易現在要制定好的旅遊計畫使他...
網易2018程式設計題之遊歷魔法王國
題目描述 魔法王國一共有n個城市,編號為0 n 1號,n個城市之間的道路連線起來恰好構成一棵樹。小易現在在0號城市,每次行動小易會從當前所在的城市走到與其相鄰的乙個城市,小易最多能行動l次。如果小易到達過某個城市就視為小易遊歷過這個城市了,小易現在要制定好的旅遊計畫使他能遊歷最多的城市,請你幫他計算...