There is a monster at each intersection except 11. When Little Q moves to the kk-th intersection, he must battle with the monster at the kk-th intersection. During the battle, he will lose aiai units of HP. And when he finally beats the monster, he will be awarded bibi units of HP. Note that when HP becomes negative(<0<0), the game will over, so never let this happen. There is no need to have a battle at the same intersection twice because monsters do not have extra life.
When all monsters are cleared, Little Q will win the game. Please write a program to compute the minimum initial HP that can lead to victory.
InputThe first line of the input contains an integer T(1≤T≤2000)T(1≤T≤2000), denoting the number of test cases.
In each test case, there is one integer n(2≤n≤100000)n(2≤n≤100000) in the first line, denoting the number of intersections.
For the next n−1n−1 lines, each line contains two integers ai,bi(0≤ai,bi≤109)ai,bi(0≤ai,bi≤109), describing monsters at the 2,3,...,n2,3,...,n-th intersection.
For the next n−1n−1 lines, each line contains two integers uu and vv, denoting a bidirectional road between the uu-th intersection and the vv-th intersection.
It is guaranteed that ∑n≤106∑n≤106.
OutputFor each test case, print a single line containing an integer, denoting the minimum initial HP.
Sample Input
1 4 2 6 5 4 6 2 1 2 2 3 3 4
Sample Output
3
思路:直接贴一个官方题解
代码如下:(不懂的可以再问我):
typedef long long LL; const int maxm = 100003; struct Node { int id, change; LL a, b; bool operator < (const Node &x) const { if(a >= b && x.a < x.b ) return true; // b > a 的优先 if(a < b && x.a >= x.b ) return false; if(a < b && x.a < x.b ) return a>x.a;//a < b,按照a从小到大 if(a >= b && x.a >= x.b) return b<x.b;//a >= b,按照b从大到小 } void operator += (const Node &n) { // A means the minimum HP to kill monster LL A = a, B = b; if(b < n.a) { A = a + n.a - b; B = n.b; } else { B = b - n.a + n.b; } a = A, b = B; } } buf[maxm]; int fa[maxm], vis[maxm], cnt, n; vector<int> G[maxm]; void build(int u, int father) { fa[u] = father; for (int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if(v != father) build(v, u); } } int Find(int u) { if(vis[fa[u]]) return fa[u] = Find(fa[u]); else return fa[u]; } void init() { cnt = 0; buf[1].a = buf[1].b = buf[1].change = 0; buf[1].id = 1; memset(vis, 0, sizeof(vis)), memset(fa, 0, sizeof(fa)); for (int i = 1; i <= n; ++i) G[i].clear(); } int main() { int t; scanf("%d", &t); while(t--) { scanf("%d", &n); init(); priority_queue<Node> q; for (int i = 2; i <= n; ++i) { scanf("%lld%lld", &buf[i].a, &buf[i].b); buf[i].id = i, buf[i].change = 0; q.push(buf[i]); } for (int i = 0; i < n - 1; ++i) { int t1, t2; scanf("%d%d", &t1, &t2); G[t1].push_back(t2), G[t2].push_back(t1); } build(1, 0); while(!q.empty()) { Node tmp = q.top(); q.pop(); int u = tmp.id; if(vis[u] || tmp.change != buf[u].change) continue; vis[u] = 1; int f = Find(u); buf[f] += buf[u]; if(f > 1) { buf[f].change = ++cnt; q.push(buf[f]); } } printf("%lld\n", buf[1].a); } return 0; }