题目描述

在游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻击。两种攻击方式都会消耗JYY一些体力。采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个怪兽可能经过若干次普通攻击后变回一个或更多同样的怪兽;而采用法术攻击则可以彻底将一个怪兽杀死。

游戏世界中一共有N种不同的怪兽,分别由1到N编号,现在1号怪兽入侵村庄了,JYY想知道,最少花费多少体力值才能将所有村庄中的怪兽全部杀死呢?

输入

第一行包含一个整数N。

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

其中第i行包含若干个整数,前三个整数为Si,Ki和Ri,表示对于i号怪兽,普通攻击需要消耗Si的体力,法术攻击需要消耗Ki的体力。同时i号怪兽死亡后会产生Ri个新的怪兽。表示一个新出现的怪兽编号。同一编号的怪兽可以出现多个。

输出

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

输入样例

4
4 27 3 2 3 2
3 5 1 2
1 13 2 4 2
5 6 1 2

输出样例

26

提示

样例解释

首先用花费4点体力用普通攻击,然后出现的怪兽编号是2,2和3。再花费10点体力用法术攻击杀死两个编号为2的怪兽。剩下3号怪兽,花费1点体力用普通攻击。此时村庄里还有编号为2和4的怪兽。最后花费11点体力用法术攻击将这两只怪兽彻底杀死。一共花费的体力是\(4+5+5+1+5+6=26\)。

数据规模

\(2≤N≤2×10^5 ,1≤R_i,ΣR_i≤10^6 ,1≤K_i,S_i≤5×10^{14}\)

主要思路

定义\(f_i\)表示完全清除第i个怪兽的体力。

不难得出 \(f_i=min(k_i,s_i+\underset{j表示i怪兽死亡后产生的新怪兽}{Σf_j})\)

而这个生成的怪兽链可能形成个环,所以我们不能用传统DP的方法做。而要使用spfa跑这个\(f_i\)。

首先需要建一张图 \(G1\) ,\(i\)死后生成了\(j\)就可以连一条\(i->j\)的边

然后需要建一张反图,用来\(f_i\)更新时,让\(f_i\)的父节点入队更新。

更新条件是\(s_i+Σf_j<f_i\)。

不难看出\(f_i\)的不可能大于\(k_i\),所以可以用\(k_i\)为\(f_i\)初始化。

代码

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std; typedef long long ll; const int N = 2e5 + 128;
const int M = 1e6 + 128; struct ios//快读
{
inline char read()
{
static const int IN_LEN = 1 << 18 | 1;
static char buf[IN_LEN], *s, *t;
return (s == t) && (t = (s = buf) + fread(buf, 1, IN_LEN, stdin)), s == t ? -1 : *s++;
} template <typename _Tp>
inline ios &operator>>(_Tp &x)
{
static char c11, boo;
for (c11 = read(), boo = 0; !isdigit(c11); c11 = read())
{
if (c11 == -1)
return *this;
boo |= c11 == '-';
}
for (x = 0; isdigit(c11); c11 = read())
x = x * 10 + (c11 ^ '0');
boo && (x = -x);
return *this;
}
} io; namespace G1
{
int head[N], nxt[M], to[M];
int p = 0; inline void add_edge(int f, int t)
{
to[++p] = t;
nxt[p] = head[f];
head[f] = p;
}
} namespace G2 //反图
{
int head[N], nxt[M], to[M];
int p = 0; inline void add_edge(int f, int t)
{
to[++p] = t;
nxt[p] = head[f];
head[f] = p;
}
} ll s[N], k[N]; ll f[N]; bool vis[N]; int n; ll spfa()
{
queue<int> Q;
for (int i = 1; i <= n; i++)
Q.push(i);
while (!Q.empty())
{
int k = Q.front();
Q.pop();
vis[k] = false; ll sum = s[k];
for (int i = G1::head[k]; i != 0; i = G1::nxt[i])
sum += f[G1::to[i]];
if (sum < f[k])
{
f[k] = sum;
for (int i = G2::head[k]; i != 0; i = G2::nxt[i])//通知父节点
if (!vis[G2::to[i]])
Q.push(G2::to[i]), vis[G2::to[i]] = true;
;
}
}
return f[1];
} int main()
{
io >> n;
for (int i = 1; i <= n; i++)
{
int r;
io >> s[i] >> k[i] >> r;
for (int j = 1; j <= r; j++)
{
int t;
io >> t;
G1::add_edge(i, t);
G2::add_edge(t, i);
}
f[i] = k[i];
}
printf("%lld", spfa());
return 0;
}

[AHOI2014/JSOI2014/一本通1722]骑士游戏 题解 (spfa做dp)的更多相关文章

  1. 2019.01.22 bzoj3875: [Ahoi2014&Jsoi2014]骑士游戏(spfa+dp)

    传送门 题意简述:nnn个怪物,对于编号为iii的怪物可以选择用aia_iai​代价将其分裂成另外的bib_ibi​个怪物或者用cic_ici​代价直接消灭它,现在问消灭编号为1的怪物用的最小代价. ...

  2. 「AHOI2014/JSOI2014」骑士游戏

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

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

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

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

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

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

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

  6. 【BZOJ3875】【AHOI2014】骑士游戏 [Spfa][DP]

    骑士游戏 Time Limit: 30 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 在这个游戏中,JYY一共有两种攻击 ...

  7. bzoj3875 【Ahoi2014】骑士游戏 spfa处理后效性动规

    骑士游戏 [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,JYY一共有两种攻 ...

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

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

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

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

  10. bzoj 3875 骑士游戏 - spfa - 动态规划

    Description  [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,J ...

随机推荐

  1. click模块解析命令行参数

    click模块解析命令行参数 安装 pip install click 操作步骤 1)使用@click.command()装饰一个函数,使之成为命令行接口 2)使用@click.option()等装饰 ...

  2. 【Java复健指南01】简介与数组

    写在最前 学习Java已经是很久之前的事情了,因为技术栈的转变,很久没有使用Java正经地开发过项目. 对于该语言的理解也是停留在表面,因此萌生了重新学习的念头.一方面是为刷算法题打基础,另一方面也是 ...

  3. 全表查询sql执行链路排查

    问题描述: 发现有sql查询全表数据,慢查询语句,根据druid上的sql监控查看到. 主要根据标红的列确定问题sql. 点击进去可以看到详细sql信息. 问题排查目标: 发现这个语句高层调用方特别多 ...

  4. 【Azure API 管理】API Management 访问限制策略[quota-by-key] 中参数 [renewal-period] 的实验和理解

    quota-by-key 策略允许根据密钥强制实施可续订或有生存期的调用量和/或带宽配额. 密钥的值可以是任意字符串,通常使用策略表达式来提供密钥. 可以添加可选增量条件,指定应在配额范围内的请求. ...

  5. C++socket中select函数

    文章参考 https://www.cnblogs.com/shmilxu/p/4835873.html

  6. Openssl命令详解 - 密钥篇

    非对称算法密钥生成和公钥提取 # ecc算法 openssl ecparam -out pri.key -name prime256v1 -genkey #生成ec密钥,国密使用-name SM2 o ...

  7. mybatis之Mapped Statements collection does not contain value for...错误原因分析

    错误原因有几种:  1.mapper.xml中没有加入namespace:  2.mapper.xml中的方法和接口mapper的方法不对应:  3.mapper.xml没有加入到mybatis-co ...

  8. 【Jmeter】性能测试--EMQ X 压测

    一.业务背景 开发人员需要验证 EMQ X 性能参数,我选用了 Jmeter 进行测试,测试其连接数.发布订阅数据指标 二.测试环境搭建 1. Jmeter 2. Jmeter 插件:需要自行从插件管 ...

  9. Spring Boot学习日记12

    学习了Thymeleaf模板引擎前端交给我们的页面,是html页面.如果是我们以前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据 ...

  10. TypeScript必知三部曲(二)JSX的编译与类型检查

    在本三部曲系列的第一部中,我们介绍了TypeScript编译的两种方案(tsc编译.babel编译)以及二者的重要差异,同时分析了IDE是如何对TypeScript代码进行类型检查的.该部分基本涵盖了 ...