【BZOJ3875】[Ahoi2014]骑士游戏【最短路】【DP】

【题目链接】

对于怪物u,普通攻击打死后产生的怪物为vi。设dis[u]表示打死u的最小花费,那么有

dis[u] = min{s[u] + ∑dis[vi], k[u]}

以这个为松弛条件,跑spfa就可以啦。

然而BZOJ跑了29s...变为倒数rank1

/* Telekinetic Forest Guard */
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef unsigned long long ULL;

const int maxn = 200005, maxm = 1000005, maxq = 200005;

int n, head[maxn], cnt, q[maxq];
ULL s[maxn], k[maxn], dis[maxn];
bool vis[maxn];

struct _edge {
	int v, next;
} g[maxm << 1];

template <class nt>
inline void read(nt &x) {
	bool f = 0; x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? 1 : 0;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	if(f) x = -x;
}

inline void add(int u, int v) {
	g[cnt] = (_edge){v, head[u]};
	head[u] = cnt++;
}

inline void spfa() {
	int h = 0, t = 0;
	for(int i = 1; i <= n; i++) dis[i] = k[i], vis[q[t++] = i] = 1;
	while(h != t) {
		int u = q[h]; vis[u] = 0; h == maxq - 1 ? h = 0 : h++;
		ULL res = s[u];
		for(int i = head[u]; ~i; i = g[i].next) if(~i & 1) res += dis[g[i].v];
		if(res < dis[u]) {
			dis[u] = res;
			for(int i = head[u]; ~i; i = g[i].next) if(i & 1) if(!vis[g[i].v]) {
				q[t] = g[i].v;
				t == maxq - 1 ? t = 0 : t++;
			}
		}
	}
}

int main() {
	read(n);
	for(int i = 1; i <= n; i++) head[i] = -1; cnt = 0;

	for(int i = 1, x; i <= n; i++) {
		read(s[i]); read(k[i]);
		for(read(x); x; x--) {
			int u; read(u);
			add(i, u); add(u, i);
		}
	}

	spfa();

	printf("%llu\n", dis[1]);
	return 0;
}
时间: 2024-08-03 15:04:13

【BZOJ3875】[Ahoi2014]骑士游戏【最短路】【DP】的相关文章

bzoj3875 [Ahoi2014]骑士游戏

Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻击.两种攻击方式都会消耗JYY一些体力.采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个怪兽可能经过若干次普通攻击后变回一个或更多同样的怪兽:而采用法术攻击则可以彻底将一个怪兽杀死.当然了,一般来说,相比普通攻击,

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

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3875 分析: 类似于spfa求最短路,设d[i]表示完全消灭i号怪物的最小花费,我们对d[]进行动态更新 我们可以把问题反向:一开始所有怪物都存活,我们要找到一个怪物合成方案合成1号怪物,其中合成方法有两种,一种是魔法攻击逆向产生怪物,另一种就是由某个怪物的后继怪物合成此怪物 对于第一种产生方法的表示,令初始的d[i]=k[i]即可 对于第二种产生方法的表示,也就是算法的核心——类似

BZOJ 3875 Ahoi2014 骑士游戏

3875: [Ahoi2014]骑士游戏 Time Limit: 30 Sec  Memory Limit: 256 MB Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻击.两种攻击方式都会消耗JYY一些体力.采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个

BZOJ 3875 Ahoi2014 骑士游戏 SPFA

题目大意:给定n个怪物,每个怪物可以用魔法直接干掉,或者用物理攻击使其分裂为一些其他怪物,求杀掉1号怪物的最小花销 令f[i]为杀死i号怪物的最小花销,则f[i]=min(k[i],s[i]+Σf[j]) 其中j为i用物理攻击后可以分裂为的怪物 但是直接DP有后效性,因此我们用SPFA来跑这个DP即可 注意如果每次更新一个点之后都重新计算花销会T掉 改成减掉花销的差值就好了 具体写法去看代码吧- - #include <cstdio> #include <cstring> #inc

「AHOI2014/JSOI2014」骑士游戏

「AHOI2014/JSOI2014」骑士游戏 传送门 考虑 \(\text{DP}\). 设 \(dp_i\) 表示灭种(雾)一只编号为 \(i\) 的怪物的代价. 那么转移显然是: \[dp_i = \min(K_i, S_i + \sum_{j = 1}^{R_i} dp_{v_j})\] 但是我们会发现这个东西是有后效性的... 所以我们会想要用建图然后跑一个最短路什么的来搞... 于是我们观察到上面那个 \(\text{DP}\) 式子中,\(dp_i\) 如果用后面那一项来转移,显然

uva 10269 最短路+dp

题意:有a个村庄.b个城镇, 编号分别为:1-a , a+1--a+b . 有双神奇的鞋,可以瞬时移动,可以使用k次,每次可以移动L , 但穿这双鞋的时候,不能经过城镇 , 问:从a+b 到 1 最短距离是多少? 刚开始看这个题时 , 一点思路都没有 , dp类型的题目做得太少了. 解法:进行状态压缩, 用点+使用鞋子的次数 , 来表示一个状态 , d[i][k] , 表示到 点 i 使用 k 次鞋子的最短距离是多少. 但要先进行初始化 , 求任意点之间不经过城镇的最短距离 , 用floyd算法

UVA - 10917 Walk Through the Forest (最短路+DP)

题意:Jimmy打算每天沿着一条不同的路走,而且,他只能沿着满足如下条件的道路(A,B):存在一条从B出发回家的路径,比所有从A出发回家的路径都短,你的任务是计算有多少条不同的路径 从后往前找最短路, 对于每一步要更新之后走的位置值: #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<algorithm> using namespace s

hdu 4568 Hunter 最短路+dp

Hunter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2014    Accepted Submission(s): 615 Problem Description One day, a hunter named James went to a mysterious area to find the treasures. Jame

BZOJ3875: [Ahoi2014&amp;Jsoi2014]骑士游戏

Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的骑士,用他手中的长剑去杀死入侵村庄的怪兽. [问题描述] 在这个游戏中,JYY一共有两种攻击方式,一种是普通攻击,一种是法术攻 击.两种攻击方式都会消耗JYY一些体力.采用普通攻击进攻怪兽并不能把怪兽彻底杀死,怪兽的尸体可以变出其他一些新的怪兽,注意一个怪兽可能经过若干次普通攻击后变回一个或更多同样的怪兽:而采用法术攻击则可以彻底将一个怪兽杀死.当然了,一般来说,相比普通攻