題目描述
bessie正在計畫一年一度的奶牛大集會,來自全國各地的奶牛將來參加這一次集會。當然,她會選擇最方便的地點來舉辦這次集會。
每個奶牛居住在 n(1<=n<=100,000) 個農場中的乙個,這些農場由n-1條道路連線,並且從任意乙個農場都能夠到達另外乙個農場。道路i連線農場a_i和b_i(1 <= a_i <=n; 1 <= b_i <= n),長度為l_i(1 <= l_i <= 1,000)。集會可以在n個農場中的任意乙個舉行。另外,每個牛棚中居住者c_i(0 <= c_i <= 1,000)只奶牛。
在選擇集會的地點的時候,bessie希望最大化方便的程度(也就是最小化不方便程度)。比如選擇第x個農場作為集會地點,它的不方便程度是其它牛棚中每只奶牛去參加集會所走的路程之和,(比如,農場i到達農場x的距離是20,那麼總路程就是c_i*20)。幫助bessie找出最方便的地點來舉行大集會。
輸入格式:
第一行:乙個整數 n 。
第二到 n+1 行:第 i+1 行有乙個整數 c_i
第 n+2 行到 2*n 行:第 i+n+1 行為 3 個整數:a_i,b_i 和 l_i。
輸出格式:
第一行:乙個值,表示最小的不方便值。
輸入樣例51
1002
1 3 1
2 3 2
3 4 3
4 5 3
輸出樣例
要使這個什麼不便利度最小
可以列舉每個點dfs算便利度
肯定會t
tt那麼我們可以先算出根節點的答案
根據這一開始乙個數遞推出其他的答案
因為選相鄰的點的答案是可以直接算出來的
f[csuma]=f
[fr]
+(su
m−si
z[ca
])∗e
dge[
i].d
is−s
iz[c
a]∗e
dge[
i].d
is
f[ca] = f[fr] + (sum - siz[ca]) * edge[i].dis - siz[ca] * edge[i].dis
f[ca]=
f[fr
]+(s
um−s
iz[c
a])∗
edge
[i].
dis−
siz[
ca]∗
edge
[i].
dis
sumsu
m是奶牛總共的個數
s iz
sizsi
z是子樹大小
選樣例模擬一下即可
選了另乙個點後這個點的不便利度應該怎麼從上乙個答案推過來
很顯然有的點往前走了有的點往後退了
有一點點容斥?
至此。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define a 1000010
#define b 2010
#define ll long long
using
namespace std;
struct node edge[a]
;int head[a]
, num_edge;
void
add_edge
(int from,
int to,
int dis)
ll siz[a]
, dis[a]
, f[a]
, ans = long_long_max, sum;
int n, a, b, c;
void
dfs(
int fr,
int fa)
}voiddd(
int fr,
int fa)
}int
main
(int argc,
const
char
**argv)
dfs(1,
0); f[1]
= dis[1]
;dd(1
,0);
cout << ans << endl;
}
P2986 USACO10MAR 偉大的奶牛聚集
題意 給一棵 n 個點的邊 點權樹,求帶權重 思路 其實這題和之前那個 sta 有點像,我們同樣只需要預處理出乙個f u 代表以 u 為集合點的方便程度,那麼我們就可以o 1 的轉移了 假設 v 是 u 的兒子,f v f u siz v len n siz v len f u n 2 siz v ...
洛谷P2986 偉大的奶牛聚集
給定一棵樹,樹上節點有點權 邊有邊權,求出乙個點ans,使得cost最小,其中 cost sum limits 樹形dp 依舊是通過兩次dfs解決 核心思想還是 二次掃瞄與換根法 名詞出自lyd 演算法競賽高階指南 我們假定1為根並且第一遍dfs求出當ans位於1時的代價dis 顯然存在 dis i...
USACO10MAR 偉大的奶牛聚集
因為是英文題,題目不再重複。給你一棵無根樹,每條邊有邊權,每個點有點權,要你選乙個點,使每個點到這個點的距離 點權的和最小,求這個值。設dis u 為u所有後代到它的距離 點權,sum u 為u所有後代的點權和包括u 先以1為根dfs一遍,預處理出所有的dis,sum 然後問題就變成了更換這棵樹的根...