在x森林裡,上帝建立了生命之樹。
他給每棵樹的每個節點(葉子也稱為乙個節點)上,都標了乙個整數,代表這個點的和諧值。
上帝要在這棵樹內選出乙個非空節點集s,使得對於s中的任意兩個點a,b,都存在乙個點列 使得這個點列中的每個點都是s裡面的元素,且序列中相鄰兩個點間有一條邊相連。
在這個前提下,上帝要使得s中的點所對應的整數的和盡量大。
這個最大的和就是上帝給生命之樹的評分。
經過atm的努力,他已經知道了上帝給每棵樹上每個節點上的整數。但是由於 atm 不擅長計算,他不知道怎樣有效的求評分。他需要你為他寫乙個程式來計算一棵樹的分數。
第一行乙個整數 n 表示這棵樹有 n 個節點。
第二行 n 個整數,依次表示每個節點的評分。
接下來 n-1 行,每行 2 個整數 u, v,表示存在一條 u 到 v 的邊。由於這是一棵樹,所以是不存在環的。
輸出一行乙個數,表示上帝給這棵樹的分數。
51 -2 -3 4 5
4 23 1
1 22 5
首先將樹確定乙個根,然後從根開始向下搜尋,確定是否加上其子樹的值(當子樹和是正數就加,因為有貢獻,反之不加)因為是討論子樹,所以必定是在同一集合內
搜尋用到了無根轉有根的技巧
#include
#include
#include
using
namespace std;
const
int maxn =
1e6;
long
long n,w[maxn]
,ww[maxn]
,ans;
vector<
int> ve[maxn]
;//鄰接表
void
dfs(
int root,
int fa)}}
if(ww[root]
>ans)ans=ww[root]
;//任意乙個節點都可以是最大權值和子樹的根
}int
main()
for(
int i=
0;i1;i++
)//輸入處理完畢
dfs(1,
0); cout
}
無根樹轉有根樹
乙個n n 1000000 個結點的無根樹的各條邊,並指定乙個根結點,要求把樹轉化為有根樹。輸入 結點的數目n,無根樹的各條邊,輸入乙個根結點號。輸出 各個結點的父親編號。執行結果 演算法實現 為方便起見,我們用了stl中的vector來儲存邊,g u 表示u結點的相鄰結點的編號。樹的儲存結構定義 ...
無根樹轉有根樹
輸入乙個n個節點的無根樹的各條邊,並指定乙個根節點,要求把該樹轉化為有根樹,輸出各個節點的父節點編號。樹是一種特殊的圖,因此可以使用鄰接矩陣來表示。如果使用二維陣列來儲存鄰接矩陣,則需要o n2 個元素的空間,因此改用vector陣列。從根節點開始對樹進行dfs。遍歷到每個節點時,使用陣列p來儲存該...
無根樹轉有根樹
1 include 2 include 3 include 4 include 5 include 6 include 7 include 8 include 9 include 10 include 11 define maxn 1000000 10 12 define inf 100000000...