rt,考场打了BCD,但是0pts。
//xagxyzcjzx zpn cy SN-S00170 GD-S0287
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a[100005], b[100005], c[100005];
vector<int> g[100005];
int n, cnt, ans;//数ci,若cigma(ci) = 0贪心,但是我tcl,不会贪心,只会链和菊花图
int lians, times[100005];//判链
int jhts;//判菊花图
bool check(int days, int u)//所需时间和节点编号
{
int h = 0;
for(int i = times[u] + 1; i <= times[u] + days; i++)
{
if(h >= a[u])break;
h += max((long long)1, b[u] + i * c[u]);
}
return (h >= a[u]);
}
void bsearch(int x)
{
int l = 0, r = 1e9, sum;
while(l <= r)
{
int mid = l + (r - l) / 2;
//cout << mid << endl;
if(check(mid, x)) sum = mid, r = mid - 1;
else l = mid + 1;
}
times[x] = sum;
}
void lian()
{
//1.计算出每个节点长成要多久(模拟或数学)
for(int i = 1; i <= n; i++)
{
times[i] = i;
bsearch(i);
}
//2.求出最大值,即为答案
for(int i = 1; i <= n; i++)ans = max(ans, times[i]);
}
struct node
{
int val, id;
}p[100005];
bool cmp(node x, node y)
{
return x.val > y.val;
}
void jht()
{
for(int i = 1; i <= n; i++)
{
bsearch(i);
if(i != 1)p[i].val = times[i], p[i].id = i;
}
sort(p + 2, p + n + 1, cmp);
for(int i = n; i > 1; i--)times[p[i].id] += i;
for(int i = 1; i <= n; i++)ans = max(ans, times[i]);
}
int days;
void dfs(int u)
{
days++;
times[u] += days;
if(g[u].size() != 0)
{
if(times[g[u][0]] > times[g[u][1]])
{
dfs(g[u][0]), dfs(g[u][1]);
}
else
{
dfs(g[u][1]), dfs(g[u][0]);
}
}
}
void bitree()
{
for(int i = 1; i <= n; i++)
{
bsearch(i);
}
dfs(1);
for(int i = 1; i <= n; i++)ans = max(ans, times[i]);
}
signed main()
{
//freopen("tree.in", "r", stdin);
//freopen("tree.out", "w", stdout);
cin >> n;
for(int i = 1; i <= n; i++)cin >> a[i] >> b[i] >> c[i], cnt += c[i];
int u, v;
for(int i = 1; i < n; i++)
{
cin >> u >> v, g[u].push_back(v);
if(u + 1 != v)lians = 1;
if(u != 1)jhts = 1;
}
if(!lians)
{
lian();
}
else if(!jhts)
{
jht();
}
else
{
bitree();
}
cout << ans;
return 0;
}