一顆樹有 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日。令小明頭疼的是,這些日期採用的格式非常不統一,有採用年 月 日的,有採用月 日 年的,還有採用日 月 年的。更加麻煩的是,年份也都省略了前兩位,使得文獻上的乙個日期,存在很多可能的日...