Day3-A-Problem H. Monster Hunter HDU6326

Little Q is fighting against scary monsters in the game ``Monster Hunter''. The battlefield consists of  nn intersections, labeled by 1,2,...,n1,2,...,n, connected by n1n−1bidirectional roads. Little Q is now at the 11-th intersection, with XX units of health point(HP). 
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(1T2000)T(1≤T≤2000), denoting the number of test cases. 
In each test case, there is one integer n(2n100000)n(2≤n≤100000) in the first line, denoting the number of intersections. 
For the next n1n−1 lines, each line contains two integers ai,bi(0ai,bi109)ai,bi(0≤ai,bi≤109), describing monsters at the 2,3,...,n2,3,...,n-th intersection. 
For the next n1n−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 n106∑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;
}
View Code
 
 

 

 

 

转载于:https://www.cnblogs.com/GRedComeT/p/11263078.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值