HDU暑假多校第三场H.Monster Hunter
一、题意
给定一个树状地图,每个树节点上有一只怪物,打死一只怪物的过程中将会消耗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的情况下>如何进行选择。于是有:
- 如果两只怪物的b都大于a,则优先打击a更小的那个怪物。
- 如果一只怪物a<b,另一只a>b则优先打击a<b的。
- 如果两只怪物的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的更多相关文章
- 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论
LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...
- HDU暑假多校第八场G-Card Game
一.题意 给出N个卡牌,卡牌的正反两面具有两个数字,取值范围为[1,2*n],给出若干个默认正面向上的卡牌,求最小反转多少张卡牌可以使得,每张卡牌朝上的面上都有一个不同的数字,同时满足最小反转次数的反 ...
- HDU暑假多校第八场J-Taotao Picks Apples
一.题意 给定一个序列,之后给出若干个修改,修改的内容为在原序列的基础上,将某一位元素的值改成给定的值<每次修改相互独立,不保存修改后的结果>.之后询问,在选择第一位元素的情况下,最长递增 ...
- HDU暑假多校第六场K-werewolf
一.题意 好人必然说真话,坏人不一定说真话,给定N个人的言论<每人一个发言.不谈及自己>,要求指出有多少个人一定是好人,有多少个人一定是坏人.#define 狼人 坏人#define 村民 ...
- HDU暑假多校第四场J-Let Sudoku Rotate
一.题意 Sudoku is a logic-based, combinatorial number-placement puzzle, which is popular around the wor ...
- [题解]Magic Line-计算几何(2019牛客多校第三场H题)
题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...
- 2019 牛客多校第三场 H Magic Line
题目链接:https://ac.nowcoder.com/acm/contest/883/H 题目大意 给定 N 个不同的整数点,N 为偶数,求一条直线,这条直线能把这 N 个点对半分开,输出这条直线 ...
- 2019牛客多校第三场H Magic Line 思维
Magic Line 题意 给出n(偶)个整点 整点范围1000,找出一条直线,把n个点分成均等的两部分 分析 因为都是整数,并且范围比较小,所以直接按x排序找到在中间那一部分,并且把中间那一部分的点 ...
- [题解] 2019牛客暑期多校第三场H题 Magic Line
题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意:二维平面上有n个不同的点,构造一条直线把平面分成两个点数相同的部分. 题解:对这n个点以x为第一关键 ...
随机推荐
- static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
查看HashMap源码,发现这个static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 值为16. 这个是位移算法. 例如: 4<& ...
- x86 分页机制——虚拟地址到物理地址寻址
x86下的分页机制有一个特点:PAE模式 PAE模式 物理地址扩展,是基于x86 的服务器的一种功能,它使运行 Windows Server 2003, Enterprise Edition 和 Wi ...
- May 10th 2017 Week 19th Wednesday
Imagination is the source of creation. 想象是创作之源. Sometimes, creation and innovation are very simple, ...
- typescript 添加基础类型的扩展方法
以时间转换为案例: //声明接口,也是在声明date这个基础类型要定义一个format的扩展方法,不写接口声明会报错 interface Date { Format(fmt:string):strin ...
- POJ 2531 深搜剪枝
题意:全局最大割. 分析:有相应的算法,数据量很小,可以枚举源点,汇点,最大流. 这里用DFS,状态定义:分成两个集合,刚开始S集合全部点,然后一个一个放,这是一个回溯的过程. 没剪枝也过了. 剪枝技 ...
- redis未授权访问getshell
redis未授权访问的问题一年前就爆了,当时刚开始学安全,还不太懂.今天借着工作的机会来搞一把,看看能不能拿下一台服务器.其实前几天就写好了一直想找个实际环境复现一下,一直没有找到,只说下大致思路. ...
- 【洛谷P1538】迎春舞会之数字舞蹈
迎春舞会之数字舞蹈 题目链接 一道奇怪的模拟题, 先将样例输出复制下来,观察观察 -- -- -- -- -- -- -- -- ① | | | | | | | | | | | | | | ② | | ...
- ActionBar 的应用
转载:http://blog.csdn.net/yuxlong2010 作为Android 3.0之后引入的新的对象,ActionBar可以说是一个方便快捷的导航神器.它可以作为活动的标题,突出活动的 ...
- Android学习笔记_9_SQLiteOpenHelper对象之数据库增删改查以及事务回滚操作
一.SQLite数据库: 在Android平台上,集成了一个嵌入式关系型数据库—SQLite,SQLite3支持 NULL.INTEGER.REAL(浮点数字).TEXT(字符串文本)和BLOB(二进 ...
- centos6: mysql+nginx+php
安装配置: mysql: http://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/ yum repolist enabled | grep mys ...