[英]Find max subset of tree with max distance not greater than K
我在名為“Far Vertices”的訪談街遇到了動態編程問題。
問題是:
您將獲得一個具有N個頂點和N-1個邊的樹。 您的任務是盡可能少地標記,以便兩個未標記頂點之間的最大距離小於或等於K.您應該將此值寫入輸出。 兩個頂點i和j之間的距離定義為為了從頂點j到達頂點i而必須通過的最小邊數。
我試圖從樹的每個節點做dfs,以便找到節點的最大連通子集,這樣每對子集的距離都不超過K.但我無法定義狀態,並且之間的轉換狀態。
有沒有人可以幫助我?
謝謝。
問題主要在於找到直徑<= k的最大子樹,並從n中減去它的大小。 您可以使用DP解決它。
一些有用的觀察:
以節點v(T(v))為根的樹的直徑是:
由於我們關心最大化樹的大小和樹的邊界直徑,我們可以翻轉上面的內容來建議每個子樹的限制:
現在是棘手的一點。 如果n有多個子節點,我們必須找到通過為每個子節點分配可用深度而產生的所有可能的樹大小。 所以說我們處於深度3,k = 7,我們還有4個深度可以玩。 如果我們有三個孩子,我們可以將所有4個分配給1個孩子,3個分配給1個孩子,1個分配給2個孩子,2個分配給1個孩子,1個孩子分配給2個孩子和3個孩子等。我們必須小心謹慎,確保我們不要超過直徑k。 您可以使用本地DP執行此操作。
我們想要的每個節點都是計算maxSize(d),它給出了以該節點為根的樹的最大尺寸,直到d深,直徑<= k。 如上所述(例如,對於一個孩子,v.maxSize(i)= c.maxSize(i-1)+ 1,v.maxSize(0)= 1),具有0和1個孩子的節點很容易計算出來。 。 有2個或更多子節點的節點,你計算dp [i] [j],它給出了一個k直徑綁定樹的最大大小,使用最多j個孩子占用j深度。 遞歸是dp [i] [j] = max(child(i).maxSize(m-1)+ dp [i-1] [min(j,k-m)],m從1到j.d [ i] [0] = 1.這就是說,嘗試給第i個孩子1到j深度,並將剩余的可用深度給予前面的節點。“剩余的可用深度”是j的最小值,深度我們正在使用或者k-m,因為給予其余的深度i +深度不能超過k。將dp的最后一行的值傳遞給該節點的maxSize表。如果你使用a運行上面的深度限制的DFS,它將以正確的順序計算所有必需的maxSize條目,節點v的答案是v.maxSize(k)。然后你對樹中的每個節點執行一次,答案是最大的找到的價值。
對不起,解釋的混亂性質。 我很難思考,難以描述。 通過一些簡單的例子可以使它更清晰。 我沒有計算復雜性,但是n很小,它在Scala中經歷了.5到1s的所有測試用例。
我可以注意到一些基本的東西(對其他人來說可能非常明顯):1。兩個給定頂點之間只有一條路線可能。 2.最遠的頂點是只有一個外邊緣的頂點。
現在來解決這個問題。
我將從只有一條邊的頂點集開始,並稱之為EDGE []計算EDGE []中頂點之間的距離。 這將給你(EDGE [i],EDGE [j],距離)值對
對於EDGE中距離> K的所有頂點對,DO EDGE [i] .occur ++,EDGE [i] .distance = MAX(EDGE [i] .distance,distance)EDGE [j] .occur ++,EDGE [ j] .distance = MAX(EDGE [j] .distance,distance)
找到EDGE []中的候選人,這些候選人與那些最大(距離)標記最大(出現)
重復直到所有邊緣頂點對的距離小於或等於K.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.