题目

思博贪心题写了一个半小时没救了,我也没看出这是一个\(spfa\)来啊

设\(dp_i\)表示彻底干掉第\(i\)只怪物的最小花费,一个非常显然的事情,就是对于\(k_i\)值最小的怪物满足\(dp_i=k_i\)

非常好理解,反正到最后都要干掉这个怪物,何必再把它干成别的怪物

于是我们按照\(k_i\)的值先排序一下,另外维护一个小根堆

如果堆里没有点或者堆顶的\(dp\)值比当前的\(k\)要大,我们直接令当前当前\(k_i\)值最小的点\(i\)的\(dp_i=k_i\),之后遍历所有能到达点\(i\)的点\(v\),令\(s_v+=dp_i\),如果发现点\(v\)的所有出边都被遍历了一遍,我们就令\(dp_v=\min(s_v,k_v)\),同时把这个点加入堆中

如果堆里有点且堆顶的\(dp\)小于于当前\(k\),就直接拿堆顶来更新

考虑这个做法的正确性,显然当前堆中没有节点的时候,图中任意一个点不可能只分解成已经处理好\(dp_i\)的点,于是我们必须引入剩下的\(k\)值最小的点

或者把堆中没有点的情况视为初始情况,可能这样更好理解

代码

  1. #include <bits/stdc++.h>
  2. #define re register
  3. #define LL long long
  4. #define mp std::make_pair
  5. #define min(a, b) ((a) < (b) ? (a) : (b))
  6. const int maxn = 2e5 + 5;
  7. struct E {
  8. int v, nxt;
  9. } e[1000005];
  10. LL dp[maxn], s[maxn], w[maxn];
  11. int head[maxn], vis[maxn], c[maxn], p[maxn];
  12. int n, num, top;
  13. inline LL read() {
  14. LL x = 0;
  15. char c = getchar();
  16. while (c < '0' || c > '9') c = getchar();
  17. while (c >= '0' && c <= '9') x = (x << 3ll) + (x << 1ll) + c - 48, c = getchar();
  18. return x;
  19. }
  20. typedef std::pair<LL, int> pii;
  21. std::priority_queue<pii, std::vector<pii>, std::greater<pii> > q;
  22. inline int cmp(int a, int b) { return s[a] < s[b]; }
  23. inline void del(int x) {
  24. vis[x] = 1;
  25. for (re int i = head[x]; i; i = e[i].nxt) {
  26. if (vis[e[i].v])
  27. continue;
  28. w[e[i].v] += dp[x];
  29. c[e[i].v]--;
  30. if (!c[e[i].v])
  31. vis[e[i].v] = 1, dp[e[i].v] = min(w[e[i].v], s[e[i].v]), q.push(mp(dp[e[i].v], e[i].v));
  32. }
  33. }
  34. inline void add(int x, int y) {
  35. e[++num].v = y;
  36. e[num].nxt = head[x];
  37. head[x] = num;
  38. }
  39. int main() {
  40. n = read();
  41. for (re int x, i = 1; i <= n; i++) {
  42. w[i] = read(), s[i] = read(), c[i] = read();
  43. for (re int j = 1; j <= c[i]; j++) x = read(), add(x, i);
  44. }
  45. for (re int i = 1; i <= n; i++) p[i] = i;
  46. std::sort(p + 1, p + n + 1, cmp);
  47. int now = 1, tot = 0;
  48. while (tot < n) {
  49. while (vis[p[now]]) ++now;
  50. if (!q.empty() && (q.top().first < s[p[now]] || now > n))
  51. tot++, del(q.top().second), q.pop();
  52. else
  53. tot++, dp[p[now]] = s[p[now]], del(p[now++]);
  54. }
  55. printf("%lld\n", dp[1]);
  56. return 0;
  57. }

[AHOI2014/JSOI2014]骑士游戏的更多相关文章

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

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

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

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

  3. BZOJ3875 AHOI2014/JSOI2014骑士游戏(动态规划)

    容易想到设f[i]为杀死i号怪物所消耗的最小体力值,由后继节点更新.然而这显然是有后效性的,正常的dp没法做. 虽然spfa已经死了,但确实还是挺有意思的.只需要用spfa来更新dp值就可以了.dij ...

  4. p4042 [AHOI2014/JSOI2014]骑士游戏

    传送门 分析 我们发现对于一个怪物要不然用魔法代价使其无需考虑后续点要么用普通攻击使其转移到他所连的所有点上且所有边大于0 所以我们可以先将一个点的最优代价设为魔法攻击的代价 之后我们倒着跑spfa求 ...

  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&Jsoi2014]骑士游戏

    [传送门:BZOJ3875] 简要题意: 给出n种怪物,每种怪物都带有三个值,S[i],K[i],R[i],分别表示对他使用普通攻击的花费,使用魔法攻击的花费,对他使用普通攻击后生成的其他怪物. 每种 ...

  8. LUOGU P4042 [AHOI2014/JSOI2014]骑士游戏 (spfa+dp)

    传送门 解题思路 首先设\(f[x]\)表示消灭\(x\)的最小花费,那么转移方程就是 \(f[x]=min(f[x],\sum f[son[x]] +s[x])\),如果这个转移是一个有向无环图,那 ...

  9. 洛谷 P4042 [AHOI2014/JSOI2014]骑士游戏

    题意 有\(n\)个怪物,可以消耗\(k\)的代价消灭一个怪物或者消耗\(s\)的代价将它变成另外一个或多个新的怪物,求消灭怪物$的最小代价 思路 \(DP\)+最短路 这几天做的第一道自己能\(yy ...

随机推荐

  1. PHP setrawcookie() 函数

    定义和用法 setrawcookie() 函数不对 cookie 值进行 URL 编码,发送一个 HTTP cookie. cookie 是由服务器发送到浏览器的变量.cookie 通常是服务器嵌入到 ...

  2. NX二次开发-UFUN工程图插入PNG图片UF_DRF_create_image_from_file

    #include <uf.h> #include <uf_drf.h> UF_initialize(); //插入PNG char* file_name = "D:\ ...

  3. NX二次开发-UFUN工程图更新视图UF_DRAW_update_one_view

    NX9+VS2012 #include <uf.h> #include <uf_draw.h> #include <uf_obj.h> #include <u ...

  4. Tomcat debug 模式, Application一直reload,导致内存溢出

    在server.xml配置文件中,将reloable改为false.

  5. mysql数据库中的索引介绍与优化(转)

    一.什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表 ...

  6. Greenplum(PostgreSql)中函数内游标的使用实例

    直接上代码,具体整体函数定义就不上了,只写关键部分: --定义两个变量 DECLARE CCUR REFCURSOR; -- 游标变量 RECORD1 RECORD; -- 记录变量,用来存储游标遍历 ...

  7. 『BASH』——Learn BashScript from Daniel Robbins——[001-002]

    ABSTRACT: Daniel Robbins is best known as the creator of Gentoo Linux and author of many IBM develop ...

  8. char型指针的初始化问题

    方法一:char *str = “abcd“区别在于你这里赋给str的是一个常量字符串,存储在静态全局区,因此str也成了一个指向常量的指针,不能通过指针对常量内容做任何更改,例如*(ch+2)='y ...

  9. 13-Ubuntu-查阅终端命令版本信息和帮助信息

    查看版本信息: 终端命令 --version 查看帮助信息: 终端命令 --help 注: 待查阅的命令 后面有两个减号-- 例:查看终端命令ls的版本和帮助信息 ls --version ls -- ...

  10. Lucene 搜索方式

    Lucene 的搜索方式包括:词项查询(TermQuery) / 布尔查询(BooleanQuery) / 短语查询(PhraseQuery) / 范围查询(RangeQuery) / 百搭查询(Wi ...