ACWING115 給樹染色(貪心)

2021-10-03 06:35:34 字數 2991 閱讀 6000

一顆樹有 n 個節點,這些節點被標號為:1,2,3…n,每個節點 i 都有乙個權值 a[i]。

現在要把這棵樹的節點全部染色,染色的規則是:

根節點r可以隨時被染色;對於其他節點,在被染色之前它的父親節點必須已經染上了色。

每次染色的代價為t*a[i],其中t代表當前是第幾次染色。

求把這棵樹染色的最小總代價。

輸入格式

第一行包含兩個整數 n 和 r ,分別代表樹的節點數以及根節點的序號。

第二行包含 n 個整數,代表所有節點的權值,第 i 個數即為第 i 個節點的權值 a[i]。

接下來n-1行,每行包含兩個整數 a 和 b ,代表兩個節點的序號,兩節點滿足關係: a 節點是 b 節點的父節點。

除根節點外的其他 n-1 個節點的父節點和它們本身會在這 n-1 行中表示出來。

同一行內的數用空格隔開。

輸出格式

輸出乙個整數,代表把這棵樹染色的最小總代價。

資料範圍

1≤n≤1000,

1≤a[i]≤1000

輸入樣例:

5 11 2 1 2 4

1 21 3

2 43 5

輸出樣例:

33思路:

可以確定的思路是除根外全域性最大的點如果能取是一定要取的。

對於兩條能取的數鏈a1,a2,a3,a4… an 和 b1,b2,b3,b4…bm.

先取鏈1再取鏈2的花費是:

( k+

1)∗a

1+..

.+(k

+n)∗

an+(

k+n+

1)∗b

1+..

.+(k

+n+m

)∗bm

(k+1)*a1 +...+(k+n)*an+(k+n+1)*b1+...+(k+n+m)*bm

(k+1)∗

a1+.

..+(

k+n)

∗an+

(k+n

+1)∗

b1+.

..+(

k+n+

m)∗b

m 先取鏈2再取鏈1的花費是:

( k+

1)∗b

1+..

.+(k

+m)∗

bm+(

k+m+

1)∗a

1+..

.+(k

+m+n

)∗an

(k+1)*b1+...+(k+m)*bm+(k+m+1)*a1+...+(k+m+n)*an

(k+1)∗

b1+.

..+(

k+m)

∗bm+

(k+m

+1)∗

a1+.

..+(

k+m+

n)∗a

n 作差得:∑a/

n−∑b

/m

∑a/n-∑b/m

∑a/n−∑

b/m那麼鏈條可以合併成乙個數,權值為總和除以數量。

那麼我們從最大權值的點開始合併,依靠鍊錶得到取數的順序(維護一條鏈的末尾位置)。最後從根節點開始遍歷獲得花費。

使用了map優化尋找最大節點的過程,複雜度 o(nlogn)。

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

1005

;int vis[maxn]

,num[maxn]

,fa[maxn]

;int lst[maxn]

,nex[maxn]

;//nex表示這個節點對應的下乙個節點,lst表示這個鍊錶最後乙個節點

double c[maxn]

,val[maxn]

,v[maxn];;

struct node

node

(int id,

int v,

int _num):id

(id),v

(v),

_num

(_num)

bool

operator

<

(const node &rhs)

const};

mapint>mp;

intmain()

num[i]=1

; lst[i]

= i;nex[i]

= i;

}for

(int i =

1;i < n;i++

)

mapint>

::iterator it;

for(

int i =

1;i < n;i++

)

nex[lst[f]

]= k;

lst[f]

= lst[k];if

(f != r)

num[f]

+= num[k]

; val[f]

+= val[k]

; c[f]

= val[f]

/ num[f];if

(f != r)

mp[node

(f,(

int)val[f]

,num[f])]

=1; vis[k]=1

;}ll ans =0;

for(

int i =

1;i <= n;i++

)printf

("%lld\n"

,ans)

;return0;

}

AcWing演算法基礎1 1

排序 快速排序 快排 寫題的時候用的不多基本都是直接sort 面試可能要手擼快排,上模板 1 void quick sort int q,int l,intr 2 12 quick sort q,l,j quick sort q,j 1 r 13 模板題 給定你乙個長度為n的整數數列。請你使用快速排...

acwing藍橋杯c AB組)1 1 遞迴

整理自acwing y總課程藍橋杯c ab組輔導課 試聽課 嗶哩嗶哩 bilibili 題目描述 抽象出資料型別 dfs,圖論,dp,貪心等 遞迴引入 自己呼叫自己 列如斐波那契數列1,2,3,5,8,13 include include using namespace std intf int n...

AcWing 日期問題

小明正在整理一批歷史文獻。這些歷史文獻 現了很多日期。小明知道這些日期都在1960年1月1日至2059年12月31日。令小明頭疼的是,這些日期採用的格式非常不統一,有採用年 月 日的,有採用月 日 年的,還有採用日 月 年的。更加麻煩的是,年份也都省略了前兩位,使得文獻上的乙個日期,存在很多可能的日...