NOIP2016提高A組五校聯考2 tree

2021-09-25 02:29:27 字數 1460 閱讀 7680

description

給一棵n 個結點的有根樹,結點由1 到n 標號,根結點的標號為1。每個結點上有乙個物品,第i 個結點上的物品價值為vi。

你需要從所有結點中選出若干個結點,使得對於任意乙個被選中的結點,其到根的路徑上所有的點都被選中,並且選中結點的個數不能超過給定的上限lim。在此前提下,你需要最大化選中結點上物品的價值之和。

求這個最大的價值之和。

input

第一行為兩個整數n; lim

接下來n 行,第i 行包含乙個整數vi,表示結點i 上物品的價值。

接下來n- 1 行,每行包含兩個整數u; v, 描述一條連線u; v 結點的樹邊。

output

輸出一行答案。

sample input

6 4-54-6

6963 2

3 12 4

2 51 6

sample output

2data constraint

對於前20% 的資料,1<=n; lim<=10

對於前60% 的資料,1<=n; lim<=100

對於100% 的資料,1<=n; lim<=3000; |vi| <=10^5 資料有梯度,保證給出的是合法的樹。..

...分析

把條件轉化,設原樹有根,如果乙個結點不選,那麼以其為根的子樹都不能選。

顯然我們可以把樹轉化成dfs序列。

設f[i][j]為前i個數中,選了j個數的最大答案。

f[i][j]=max

時間複雜度為o(n2)。..

...程式:

#include#include#include#includeusing namespace std;

struct edge

e[100000];

int a[4000],v[4000],n,lim,cnt=0,tot=0,head[100000],dfn[100000],low[100000],f[3005][3005];

void add(int x,int y)

void dfs(int x,int father)

int main()

dfs(1,0);

memset(f,128,sizeof(f));

f[0][0]=0;

for (int i=0;i<=n-1;i++)

for (int j=0;j<=lim-1;j++)

int ans=0;

for (int i=1;i<=n;i++)

for (int j=0;j<=lim;j++)

ans=max(ans,f[i][j]);

printf("%d",ans);

fclose(stdin);

fclose(stdout);

return 0;

}

NOIP2016提高A組五校聯考1 道路規劃

我們考慮,當現在有乙個合法的集合時,如何往裡面增加乙個點,使這個集合仍然合法。假設現在有乙個合法的集合,那麼當我們加入乙個點,它的道路穿過來整個集合,那麼 然後搞一遍最長下降子串行就可以了。include include include include include const int maxlo...

NOIP2016提高A組五校聯考1 挖金礦

剛看到這題時,還在想怎麼貪心,然後很快的打完之後發現貪心是錯的。然後仔細的看了看範圍,哈哈,這不是二分嗎。二分出乙個mid,然後在所有行裡面用mid j 字首和然後找乙個最大值。最後把這些最大值加起來,判斷一下就好了。include include include include include i...

NOIP2016提高A組五校聯考1 挖金礦

答案,保留4位小數 4 3 4 3 3 5 1 6 2 6 1 3 2 9 4.4286 n m 100000 很簡單的一道題 設sum i j 表示第i列向下挖j行的字首和 假設第i列挖h i 行 設二分的答案是m,答案如果合法,那麼 n i 1s um i h i ni 1 h i m 移項 i...