蓝桥杯 算法训练(四)结点选择(树形动态规划)
結點選擇(樹形動態規劃)C語言
問題描述
有一棵 n 個節點的樹,樹上每個節點都有一個正整數權值。如果一個點被選擇了,那么在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?
輸入格式
第一行包含一個整數 n 。
接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。
接下來一共 n-1 行,每行描述樹上的一條邊。
輸出格式
輸出一個整數,代表選出的點的權值和的最大值。
樣例輸入
5
1 2 3 4 5
1 2
1 3
2 4
2 5
樣例輸出
12
樣例說明
選擇3、4、5號點,權值和為 3+4+5 = 12 。
數據規模與約定
對于20%的數據, n <= 20。
對于50%的數據, n <= 1000。
對于100%的數據, n <= 100000。
權值均為不超過1000的正整數。
前面也說了,這道題筆者花了相當長的時間,但其實細究起來,最重要的就三個點:
1.建樹
(但這道題并不是簡單的單個頭結點,每個結點只有一個父結點的那種普通的樹,它實際是個無向圖!)
2.遞推式
(這個難度比較小),但是不太好解釋 ,講不清楚請原諒哈~~?( ^ ? ^ *) ,直接寫基本思路:
深度遍歷每一個結點,每個結點都進行一次判斷:
如果取這個結點,那么該結點的子結點就不取,如果不取該結點,那么它的子結點有兩種情況:可以取,也可以不取!
于是有狀態方程:
dp[x][0]表示x結點不選中時最大的權值,dp[x][1]表示x結點選中時最大的權值
狀態轉移方程:dp[x][1] = dp[x][1] + dp[u][0] (u為x的子結點)
dp[x][0] = dp[x][0] + max{dp[u][0],dp[u][1]}(u為x的子結點)
(看不懂就多看幾遍,自己紙上畫一下,花點時間總是能懂的。)
3。樹(無向圖)的遍歷
(事實上,樹的遍歷還是比較容易的,只要注意多叉樹與二叉樹之間的轉換就很容易實現,祥見上一篇博客的代碼(這幾個字是鏈接))
但是!無向圖的遍歷就復雜了好多,這也是這篇博客的重點!!!
因為網上能找到的的代碼基本都是千篇一律,但那段代碼筆者是真的看不懂~~
但功夫不負有心人,我終于找到了一篇好東西!!
鏈式前向星https://blog.csdn.net/lala__lailai/article/details/79249809
以上為鏈接!
在這(兩)位大佬的幫助下!筆者終于搞懂了這段神奇的代碼!!
但是很顯然這種算法筆者很難學得會呀~~嗚嗚嗚…
哎,講得亂七八糟的,希望讀者大大們能看懂~~
看不懂就動筆一步一步跟著代碼走,相信你一定會豁(jing)然(wei)開(tian)朗(ren)的~~
以上!
</div><link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-258a4616f7.css" rel="stylesheet"></div>總結
以上是生活随笔為你收集整理的蓝桥杯 算法训练(四)结点选择(树形动态规划)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#利用反射将Datatable转化为指
- 下一篇: 思科CCNA第一学期期末考试答案