一、题意

  给定一个树状地图,每个树节点上有一只怪物,打死一只怪物的过程中将会消耗A点HP,打死之后将会获得B点HP。因为树状结构,所以每只怪物必须先打死父节点的怪兽之后在打死子节点的怪物。现在,给定每只怪兽的a,b和树状结构的联通关系,求初始HP最小的击败顺序。

  Little Q is fighting against scary monsters in the game ``Monster Hunter''. The battlefield consists of n intersections, labeled by 1,2,...,n, connected by n−1bidirectional roads. Little Q is now at the 1-th intersection, with X units of health point(HP).
There is a monster at each intersection except 1. When Little Q moves to the k-th intersection, he must battle with the monster at the k-th intersection. During the battle, he will lose ai units of HP. And when he finally beats the monster, he will be awarded bi units of HP. Note that when HP becomes negative(<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.

二、解题思路

  首先考虑在一般情况下<仅仅给出每只怪物的A,B的情况下>如何进行选择。于是有:

    1. 如果两只怪物的b都大于a,则优先打击a更小的那个怪物。
    2. 如果一只怪物a<b,另一只a>b则优先打击a<b的。
    3. 如果两只怪物的b都小于a,于是有,最小血量的击败方案为min(max(ai,ai+aj-bi),max(aj,aj+ai-bj)),题解提到上述计算式实际上等于比较bi和bj

  之后考虑,加入树边的情况。

  考虑使用优先队列维护最优解,则

    当某一个元素p为上述比较方案的最优解时,

    且p的树根如果被选择后,选择p一定是最优解。

  因此可以将p并入树根节点,后使p得所有子节点成为p的兄弟节点。——因为当p的父节点被选择后,p也已经默认被立刻选择了。

  最终,当所有节点都是根节点的子节点时,计算并比较最优解的具体状态。

  考虑一个细节:如何合并两个节点?
    设ai,aj,bi,bj为两个节点的相关变量则有:

    ak = min(max(ai,ai+aj-ai),max(aj,aj+ai-bj))

    bk = ak + bi + bj - ai - aj

#include<bits/stdc++.h>
using namespace std; #define ll long long
const ll MAXN=;
#define veci vector<int> int fa[MAXN];
int cha[MAXN]; class Node
{
public:
ll a,b,num,ver;
Node(){}
Node(const Node &n)
{
this->a = n.a;
this->b = n.b;
this->num = n.num;
this->ver = n.ver;
}
bool operator < (Node const n)const{
ll tmpa = this->b - this->a;
ll tmpb = n.b - n.a;
if(tmpa >= && tmpb >=)return this->a > n.a;
if(tmpa >= && tmpb < )return false;
if(tmpa < && tmpb >=)return true;
if(tmpa < && tmpb < )return this->b < n.b;
}
};
Node nodes[MAXN];
int n;
veci G[MAXN]; void dfs(int now,int father)
{
fa[now] = father;
int len = G[now].size();
for(int i=;i<len;++i)
{
int tar = G[now][i];
if(tar == father)continue;
dfs(tar,now);
}
} int find_set(int tar)
{
if(cha[tar] == tar)return tar;
else return cha[tar] = find_set(cha[tar]);
} void init()
{
cin>>n;
for(int i=;i<n+;++i)
{
G[i].clear();
cha[i] = i;
}
priority_queue<Node> pq;
for(int i=;i<=n;++i)
{
cin>>nodes[i].a>>nodes[i].b;
nodes[i].num = i;
nodes[i].ver = ;
pq.push(nodes[i]);
}
for(int i=;i<n;++i)
{
int a,b;
cin>>a>>b;
G[a].push_back(b);
G[b].push_back(a);
}dfs(,); ll ans = ;
ll money = ; while(!pq.empty())
{
Node node = pq.top();
pq.pop(); int now = node.num;
if(node.ver != nodes[now].ver)continue;
int father = fa[now];
father = find_set(father);
nodes[now].ver = -;
cha[now] = cha[father];
if(father == )
{
if(node.a > money)
{
ans += node.a-money;
money = node.b;
}else{
money -= node.a;
money += node.b;
}
continue;
} nodes[father].ver ++;
ll tmp = nodes[father].b +node.b - nodes[father].a-node.a;
nodes[father].a = max(nodes[father].a, nodes[father].a + node.a - nodes[father].b);
nodes[father].b = nodes[father].a + tmp;
Node newNode(nodes[father]);
pq.push(newNode);
} cout<<ans<<"\n";
} int main()
{
cin.sync_with_stdio(false);
int t;
cin>>t;
while(t--)init(); return ;
}

HDU暑假多校第三场H.Monster Hunter的更多相关文章

  1. 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论

    LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...

  2. HDU暑假多校第八场G-Card Game

    一.题意 给出N个卡牌,卡牌的正反两面具有两个数字,取值范围为[1,2*n],给出若干个默认正面向上的卡牌,求最小反转多少张卡牌可以使得,每张卡牌朝上的面上都有一个不同的数字,同时满足最小反转次数的反 ...

  3. HDU暑假多校第八场J-Taotao Picks Apples

    一.题意 给定一个序列,之后给出若干个修改,修改的内容为在原序列的基础上,将某一位元素的值改成给定的值<每次修改相互独立,不保存修改后的结果>.之后询问,在选择第一位元素的情况下,最长递增 ...

  4. HDU暑假多校第六场K-werewolf

    一.题意 好人必然说真话,坏人不一定说真话,给定N个人的言论<每人一个发言.不谈及自己>,要求指出有多少个人一定是好人,有多少个人一定是坏人.#define 狼人 坏人#define 村民 ...

  5. HDU暑假多校第四场J-Let Sudoku Rotate

    一.题意 Sudoku is a logic-based, combinatorial number-placement puzzle, which is popular around the wor ...

  6. [题解]Magic Line-计算几何(2019牛客多校第三场H题)

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...

  7. 2019 牛客多校第三场 H Magic Line

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题目大意 给定 N 个不同的整数点,N 为偶数,求一条直线,这条直线能把这 N 个点对半分开,输出这条直线 ...

  8. 2019牛客多校第三场H Magic Line 思维

    Magic Line 题意 给出n(偶)个整点 整点范围1000,找出一条直线,把n个点分成均等的两部分 分析 因为都是整数,并且范围比较小,所以直接按x排序找到在中间那一部分,并且把中间那一部分的点 ...

  9. [题解] 2019牛客暑期多校第三场H题 Magic Line

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意:二维平面上有n个不同的点,构造一条直线把平面分成两个点数相同的部分. 题解:对这n个点以x为第一关键 ...

随机推荐

  1. Win+Tab键实现自定义程序列表间的窗口切换

    程序是用AutoHotkey语言写的, 说明: 以自己使用频率的顺序在ExeList自定义的程序间切换 切换可以以所有窗口切换,也可以按程序组切换(比如在word窗口间切换) 程序组可以分别定义排除的 ...

  2. Jmeter入门14 后置处理器JSON Extractor 提取json的多个值

    json串 []表示对象组成的数组,{}表示对象. 对象里包含多个 "属性":属性值.属性值可以是值,或数组,或对象. JSON Extractor使用json path表达式匹配 ...

  3. Android(java)学习笔记36:Scanner类使用

    1. Scanner类使用 package cn.itcast_01; /* * Scanner:用于接收键盘录入数据. * * 前面的时候: * A:导包 * B:创建对象 * C:调用方法 * * ...

  4. pthread_create & pthread_exit

    http://www.cppblog.com/saha/articles/189802.html 1.   pthread_create    #include <pthread.h>   ...

  5. LA 3415 保守的老师

    题目链接:https://vjudge.net/contest/161820#problem/E 题意: 有一些同学,要从中选出一些同学来,人数尽量多,但是,两两之间要满足至少一个条件(身高差> ...

  6. [18/11/29] 继承(extends)和方法的重写(override,不是重载)

    一.何为继承?(对原有类的扩充) 继承让我们更加容易实现类的扩展. 比如,我们定义了人类,再定义Boy类就只需要扩展人类即可.实现了代码的重用,不用再重新发明轮子(don’t  reinvent  w ...

  7. 2018.11.26 struts2流程源码

    struts2的架构图 从最上面的类开始,也就是i 我们的核心过滤器strutsPrepareAndExecuteFilter 判断当前请求是否由struts2来处理,如果是就往else走,不由它来处 ...

  8. SQL中char、varchar、nvarchar、text 的区别

    char char是定长的,也就是当你输入的字符小于你指定的数目时,char(8),你输入的字符小于8时,它会再后面补空值.当你输入的字符大于指定的数时,它会截取超出的字符. nvarchar(n) ...

  9. ROS编译工作区缺少cv_bridge的问题解决

    cv_bridge是OpenCV与ROS之间的格式转换桥梁,编译工作区时遇到报错(目标不存在),直接将cv_bridge包复制到指定的目录即可. 下载地址:https://github.com/ros ...

  10. Android学习笔记_46_Android的intent之间Object、List、List<Object>和全局变量数据的传递(Parcelable Serializable)

    转http://blog.csdn.net/pku_android/article/details/7456305 一.传递List<String>和List<Integer> ...