Time Limit: 30 Sec Memory Limit: 256 MB

Submit: 564 Solved: 304

[Submit][Status][Discuss]

Description

【故事背景】

长期的宅男生活中,JYY又挖掘出了一款RPG游戏。在这个游戏中JYY会

扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽。

【问题描述】

在这个游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻

击。两种攻击方式都会消耗JYY一些体力。采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个怪兽可能经过若干次普通攻击后变回一个或更多同样的怪兽;而采用法术攻击则可以彻底将一个怪兽杀死。当然了,一般来说,相比普通攻击,法术攻击会消耗更多的体力值(但由于游戏系统bug,并不保证这一点)。

游戏世界中一共有N种不同的怪兽,分别由1到N编号,现在1号怪兽入

侵村庄了,JYY想知道,最少花费多少体力值才能将所有村庄中的怪兽全部杀死呢?

Input

第一行包含一个整数N。

接下来N行,每行描述一个怪兽的信息;

其中第i行包含若干个整数,前三个整数为Si,Ki和Ri,表示对于i号怪兽,

普通攻击需要消耗Si的体力,法术攻击需要消耗Ki的体力,同时i号怪兽死亡后会产生Ri个新的怪兽。表示一个新出现的怪兽编号。同一编号的怪兽可以出现多个。

Output

输出一行一个整数,表示最少需要的体力值。

Sample Input

4

4 27 3 2 3 2

3 5 1 2

1 13 2 4 2

5 6 1 2

Sample Output

26

HINT

【样例说明】

首先用消耗4点体力用普通攻击,然后出现的怪兽编号是2,2和3。花费

10点体力用法术攻击杀死两个编号为2的怪兽。剩下3号怪兽花费1点体力进

行普通攻击。此时村庄里的怪兽编号是2和4。最后花费11点体力用法术攻击

将这两只怪兽彻底杀死。一共花费的体力是4+5+5+1+5+6=26。

【数据范围】

2<=N<=2*10^5,1<=Ri,Sigma(Ri)<=10^6,1<=Ki,Si<=5*10^14

Source

By 佚名上传

题解

设f[i]表示消灭i这个怪物所需要的最小花费。

f[i]一开始等于g[i];

设g[i]为用物理攻击消灭i号怪物所需的花费。

g[i]一开始等于s[i] + ∑k[i的出度];

则f[i] = min(k[i],∑f[i的出度]);

g[i]一开始等于s[i] + ∑k[i的出度];

显然g[i]这个状态不可能总是正确的。则我们需要尝试更新每一个g[i];

更新的方式是从尾往前更新。

如果发现某个x它的g值小于f值;则,我们显然可以更新那些出度有x的点三设为before的g值了。

即g[before]-=f[x];g[before]+=g[x];

因为更新了before的信息。则before之前的信息也可能更改了。则把它加进去。继续更新。

这个过程很像SPFA的更新过程。

用spfa去做吧。

建边的时候建个反图。这样就能知道某个节点它的前驱是啥了。

代码

#include <cstdio>
#include <vector>
#include <queue> using namespace std; const int MAXN = 2 * 1e5 + 10; int n;
long long si[MAXN],ki[MAXN];
vector <int> zheng[MAXN], fan[MAXN];
long long f[MAXN], g[MAXN];
queue <int> dl;
bool inque[MAXN] = { 0 }; void spfa()
{
while (!dl.empty())
{
int x = dl.front();
inque[x] = false;
dl.pop();
if (g[x] >= f[x])
continue;
int len = fan[x].size();
for (int i = 0; i <= len - 1; i++)
{
int before = fan[x][i];
g[before] -= f[x];
g[before] += g[x];
if (!inque[before])
{
inque[before] = true;
dl.push(before);
}
}
f[x] = g[x];//因为g[x] < f[x]则f[x]可以更新了
}
} int main()
{
// freopen("F:\\rush.txt", "r", stdin);
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
dl.push(i);
inque[i] = true;
scanf("%lld%lld", &si[i], &ki[i]);
int num;
scanf("%d", &num);
for (int j = 1; j <= num; j++)
{
int y;
scanf("%d", &y);
zheng[i].push_back(y);
fan[y].push_back(i);
}
}
for (int i = 1; i <= n; i++)
{
f[i] = ki[i];
g[i] = si[i];
int len = zheng[i].size();
for (int j = 0; j <= len - 1; j++)//这只是初值。之后会更新
g[i] += ki[zheng[i][j]];
}
spfa();
printf("%lld\n", f[1]);
return 0;
}

【53.90】【BZOJ 3875】 [Ahoi2014]骑士游戏的更多相关文章

  1. BZOJ 3875: [Ahoi2014]骑士游戏 dp+spfa

    题目链接: 题目 3875: [Ahoi2014]骑士游戏 Time Limit: 30 Sec Memory Limit: 256 MB 问题描述 [故事背景] 长期的宅男生活中,JYY又挖掘出了一 ...

  2. BZOJ 3875: [Ahoi2014]骑士游戏

    d[i]表示消灭i所需的最小体力值, d[i] = min(S[i], K[i]+Σd[x]), Σd[x]表示普通攻击而产生的其他怪兽. 因为不是DAG, 所以用个队列类似SPFA来更新答案. -- ...

  3. BZOJ 3875: [Ahoi2014]骑士游戏 spfa dp

    3875: [Ahoi2014]骑士游戏 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3875 Description [故事背景] 长 ...

  4. [bzoj3875] [Ahoi2014]骑士游戏

    3875: [Ahoi2014]骑士游戏 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 844  Solved: 440[Submit][Status ...

  5. [BZOJ] 3875: [Ahoi2014&Jsoi2014]骑士游戏

    设\(f[x]\)为彻底杀死\(x\)号怪兽的代价 有转移方程 \[ f[x]=min\{k[x],s[x]+\sum f[v]\} \] 其中\(v\)是\(x\)通过普通攻击分裂出的小怪兽 这个东 ...

  6. bzoj 3875: [Ahoi2014&Jsoi2014]骑士游戏【dp+spfa】

    设f[i]为杀死i的最小代价,显然\( f[i]=min(k[i],s[i]+\sum f[to]) \) 但是这个东西有后效性,所以我们使用spfa来做,具体就是每更新一个f[i],就把能被它更新的 ...

  7. [BZOJ3875][AHOI2014]骑士游戏(松弛操作)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3875 分析: 类似于spfa求最短路,设d[i]表示完全消灭i号怪物的最小花费,我们对 ...

  8. 【BZOJ3875】[Ahoi2014&Jsoi2014]骑士游戏 SPFA优化DP

    [BZOJ3875][Ahoi2014&Jsoi2014]骑士游戏 Description  [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会扮演一个英勇的 ...

  9. 「AHOI2014/JSOI2014」骑士游戏

    「AHOI2014/JSOI2014」骑士游戏 传送门 考虑 \(\text{DP}\). 设 \(dp_i\) 表示灭种(雾)一只编号为 \(i\) 的怪物的代价. 那么转移显然是: \[dp_i ...

随机推荐

  1. golang webservice[ json Martini webframe]

    golang webservice[ json Martini webframe] https://github.com/brunoga/go-webservice-sample 自己修改了一下例子, ...

  2. php学习笔记4

    PHP数据类型: String(字符串), Integer(整型), Float(浮点型), Boolean(布尔型), Array(数组), Object(对象), NULL(空值). 说明:var ...

  3. 13.Zookeeper的java客户端API使用方法

    转自:https://blog.csdn.net/jiuqiyuliang/article/details/56012027

  4. 自定义HTML标签属性

    为HTML元素添加一自定义的属性非常方便,只须将其加到尖括号中即可,与内置属性地位相等. 如我们要为TextBox元素添加属性idvalue: <input type="text&qu ...

  5. sampleviewer add menu item error 'assert'

    可以跟踪到 mfc提供的源代码内部,(注:如果打开了mfc源代码,设置了断点,但是跟不进去,那就需要更新PDB文件,具体网上搜)打开 wincore.cpp文件(D:\Program Files\Mi ...

  6. 【习题 6-7 UVA - 804】Petri Net Simulation

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟就好 [代码] /* 1.Shoud it use long long ? 2.Have you ever test sever ...

  7. MYSQL添加远程用户或允许远程访问三种方法

    添加远程用户admin密码为password GRANT ALL PRIVILEGES ON *.* TO admin@localhost IDENTIFIED BY \'password\' WIT ...

  8. JPA学习笔记(11)——使用二级缓存

    一级缓存 查询两次id为1的user User user1 = entityManager.find(User.class, 1); User user2 = entityManager.find(U ...

  9. LeetCode Algorithm 06_ZigZag Conversion

    The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like ...

  10. 电脑c盘清理

    https://www.cnblogs.com/btchenguang/archive/2012/01/20/2328320.html