BZOJ-3875: [Ahoi2014&Jsoi2014]骑士游戏(SPFA+DP)

3875: [Ahoi2014&Jsoi2014]骑士游戏

Time Limit: 30 Sec  Memory Limit: 256 MB
Submit: 976  Solved: 496
[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

好题啊,SPFA竟然还能处理有后效性的DP!!可惜读入优化的an一直开的是int……然后就wa了两次……顺带学会了对拍……收获还是颇丰滴O(∩_∩)O
题解:http://blog.csdn.net/vmurder/article/details/44040735
ps:对了有如果当前节点的额子节点更新了,应该把当前节点入队,因为当前节点可能会有更优解,所以存边的时候应该开两个前向星,一个是正边,一个是反边,反边用于寻找自己的父亲节点
 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX1=2e5+5;
 5 const int MAX2=2e6+5;
 6 int n,m;
 7 LL tot,head[MAX1],h[MAX1],adj[MAX2],ad[MAX2],ne[MAX2],next[MAX2];
 8 LL dis[MAX1],a[MAX1];
 9 queue <int> q;
10 bool t[MAX1];
11 inline LL read(){
12     LL an=0,x=1;char c=getchar();
13     while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();}
14     while (c>='0' && c<='9') {an=an*10+c-'0';c=getchar();}
15     return an*x;
16 }
17 void addedge(LL u,LL v){
18     tot++;
19     adj[tot]=v;    next[tot]=head[u]; head[u]=tot;
20     ad[tot]=u;  ne[tot]=h[v];      h[v]=tot;
21 }
22 void spfa(){
23     int i,j,u,v;
24     LL zt;
25     while (!q.empty()) q.pop();
26     memset(t,false,sizeof(t));
27     for (i=1;i<=n;i++) q.push(i),t[i]=true;
28     while (!q.empty()){
29         u=q.front();q.pop();
30         t[u]=false;zt=a[u];
31         for (i=head[u];i;i=next[i])
32             zt+=dis[adj[i]];
33         if (zt>=dis[u]) continue;
34         dis[u]=zt;
35         for (i=h[u];i;i=ne[i])
36             if (!t[ad[i]])
37                 q.push(ad[i]),t[ad[i]]=true;
38     }
39 }
40 int main(){
41     freopen ("game.in","r",stdin);
42     freopen ("game.out","w",stdout);
43     int i,j;LL x,y;
44     n=read();
45     for (i=1;i<=n;i++){
46         a[i]=read(),dis[i]=read(),x=read();
47         for (j=1;j<=x;j++){
48             y=read();
49             addedge((LL)i,y);
50         }
51     }
52     spfa();
53     printf("%lld",dis[1]);
54     return 0;
55 }
未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
原文地址:https://www.cnblogs.com/keximeiruguo/p/7700904.html