Since Boboniu finished building his Jianghu, he has been doing Kungfu on these mountains every day.
Boboniu designs a map for his n n n mountains. He uses n − 1 n−1 n−1 roads to connect all n n n mountains. Every pair of mountains is connected via roads.
For the i i i-th mountain, Boboniu estimated the tiredness of doing Kungfu on the top of it as t i t_i ti. He also estimated the height of each mountain as h i h_i hi.
A path is a sequence of mountains M M M such that for each i i i ( 1 ≤ i < ∣ M ∣ ) (1≤i<|M|) (1≤i<∣M∣), there exists a road between M i M_i Mi and M i + 1 M_{i+1} Mi+1. Boboniu would regard the path as a challenge if for each i i i ( 1 ≤ i < ∣ M ∣ ) (1≤i<|M|) (1≤i<∣M∣), h M i ≤ h M i + 1 h_{M_i}≤h_{M_{i+1}} hMi≤hMi+1.
Boboniu wants to divide all n − 1 n−1 n−1 roads into several challenges. Note that each road must appear in exactly one challenge, but a mountain may appear in several challenges.
Boboniu wants to minimize the total tiredness to do all the challenges. The tiredness of a challenge M M M is the sum of tiredness of all mountains in it, i.e. ∑ i = 1 ∣ M ∣ t M i ∑_{i=1}^{|M|}t_{M_i} ∑i=1∣M∣tMi.
He asked you to find the minimum total tiredness. As a reward for your work, you’ll become a guardian in his Jianghu.
Input
The first line contains a single integer n n n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) (2≤n≤2⋅10^5) (2≤n≤2⋅105), denoting the number of the mountains.
The second line contains n n n integers t 1 , t 2 , … , t n t_1,t_2,…,t_n t1,t2,…,tn ( 1 ≤ t i ≤ 1 0 6 ) (1≤t_i≤10^6) (1≤ti≤106), denoting the tiredness for Boboniu to do Kungfu on each mountain.
The third line contains n n n integers h 1 , h 2 , … , h n h_1,h_2,…,h_n h1,h2,…,hn ( 1 ≤ h i ≤ 1 0 6 ) (1≤h_i≤10^6) (1≤hi≤106), denoting the height of each mountain.
Each of the following n − 1 n−1 n−1 lines contains two integers u i , v i u_i, v_i ui,vi ( 1 ≤ u i , v i ≤ n , u i ≠ v i ) (1≤u_i,v_i≤n,u_i≠v_i) (1≤ui,vi≤n,ui=vi), denoting the ends of the road. It’s guaranteed that all mountains are connected via roads.
Output
Print one integer: the smallest sum of tiredness of all challenges.
Examples
input
5
40 10 30 50 20
2 3 2 3 1
1 2
1 3
2 4
2 5
output
160
input
5
1000000 1 1 1 1
1000000 1 1 1 1
1 2
1 3
1 4
1 5
output
4000004
input
10
510916 760492 684704 32545 484888 933975 116895 77095 127679 989957
402815 705067 705067 705067 623759 103335 749243 138306 138306 844737
1 2
3 2
4 3
1 5
6 4
6 7
8 7
8 9
9 10
output
6390572
Note
For the first example:
In the picture, the lighter a point is, the higher the mountain it represents. One of the best divisions is:
The total tiredness of Boboniu is ( 30 + 40 + 10 ) + ( 20 + 10 + 50 ) = 160 (30+40+10)+(20+10+50)=160 (30+40+10)+(20+10+50)=160. It can be shown that this is the minimum total tiredness.
思路参考(照搬)
纯树形 d p dp dp,但是状态的选择以及状态转移的贪心策略不太容易想到,并且还要注意一些细节。
设 f [ x ] [ 0 ] f[x][0] f[x][0]表示当 h [ f a x ] ≥ h [ x ] h[fa_x]≥h[x] h[fax]≥h[x]时以 x x x为根的子树的所有路径划分方案中 t t t值之和的最小值; f [ x ] [ 1 ] f[x][1] f[x][1]表示当 h [ f a x ] ≤ h [ x ] h[fa_x]≤h[x] h[fax]≤h[x]时以 x x x为根的子树的所有路径划分方案中 t t t值之和的最小值。
复杂度为 O ( n log n ) O(n\log n) O(nlogn)。
#include
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector
#define pii pair
#define mii unordered_map
#define msi unordered_map
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define INF 1e12
#define pr(x) cout<<#x<<": "<
using namespace std;
inline int qr() {
int f = 0, fu = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')fu = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
const int N = 2e5 + 10;
int head[N], ver[N << 1], Next[N << 1], tot;
int t[N], h[N], n;
ll f[N][2];
inline void add(int x, int y) {
ver[++tot] = y;
Next[tot] = head[x];
head[x] = tot;
}
void dp(int x, int fa) {
bool up = h[fa] >= h[x] || x == 1;
bool down = h[fa] <= h[x] || x == 1;
vector<ll> tmp;
tmp.pb(0);
ll sum = 0;
reps(x) {
int y = ver[i];
if (y == fa)continue;
dp(y, x), sum += f[y][0], tmp.pb(f[y][1] - f[y][0]);
}
if (tmp.empty()) {
f[x][0] = up ? t[x] : INF;
f[x][1] = down ? t[x] : INF;
return;
}
f[x][0] = f[x][1] = INF;
sort(++tmp.begin(), tmp.end());
int num = tmp.size();
if (up) {
ll res = sum;
repi(i, 0, num - 1) {
res += tmp[i];
f[x][0] = min(f[x][0], res + 1ll * t[x] * max(num - i - 1, i + 1 - (x == 1)));
}
}
if (down) {
ll res = sum;
repi(i, 0, num - 1) {
res += tmp[i];
f[x][1] = min(f[x][1], res + 1ll * t[x] * max(num - i - (x == 1), i));
}
}
}
int main() {
n = qr();
repi(i, 1, n)t[i] = qr();
repi(i, 1, n)h[i] = qr();
repi(i, 1, n - 1) {
int x = qr(), y = qr();
add(x, y), add(y, x);
}
dp(1, 0);
pl(max(f[1][0], f[1][1]));
return 0;
}