生命之樹 搜尋,樹的無根轉有根 藍橋杯省賽

2021-10-09 23:28:39 字數 1148 閱讀 6598

在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...