我是靠谱客的博主 现代过客,这篇文章主要介绍GDUT Krito的讨伐(bfs&&优先队列),现在分享给大家,希望可以做个参考。

题意

Description

Krito终于干掉了99层的boss,来到了第100层。第100层可以表示成一颗树,这棵树有n个节点(编号从0到n-1),树上每一个节点可能有很多只怪物。 Krito现在在0号节点,现在它想要区清除这一层所有的怪物。他现在有atk大小的攻击力。只有当你的攻击力大于这只怪物的防御力时,你才可以打败他,同时每打败只怪物,你会获得一定的攻击力加成。一个节点可能存在着不止一只怪兽,你要打败这个节点的所有怪物才能可以从这个节点通过,请问他能不能完成这个任务?注意:不要求一次性杀光一个节点里面的所有怪物。

Input

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
第1行:一个数T,表示有T个测试样例(0<=T<=50) ,接下来有T个测试样例 对于每一个测试样例: 第1行:两个整数n,m表示这棵树有n个节点,m只怪兽(0<=n<=1000 ,0<=m <=100) 第2至n-1行: 两个整数u,v表示编号为u,v之间的节点有一条无向边,题目保证不会成环。(0<=u,v<n , u!=v) >第3行: 一个整数atk,表示Krito的初始化攻击力(0<=atk<=100) 第4至3+m行:两个整数id,def,add_atk,表示在编号为id的点上,有一只防御力为def的怪物,打败后可以增加add_atk点的攻击力。(0<=add_atk,def<=100)

Output

复制代码
1
2
对于每一个测试样例,如果Krito能够清除所有的怪物,则输出“Oh yes.” 否则,输出“Good Good Study,Day Day Up.”

Sample Input

复制代码
1
2
3
4
5
6
7
8
9
10
1 5 2 0 1 0 2 2 3 2 4 11 3 10 2 1 11 0

Sample Output

复制代码
1
2
Oh yes.

思路

因为从根节点开始,必须打败当前节点的所有怪物,才可以进入下一节点。贪心思想,先选择防御力低的怪物总是不会更坏。
所以用一优先队列维护我们可以攻击到到怪物,一旦某节点怪物全杀完,则将其子节点怪物加入队列。
如果当前最小防御力怪物都不能消灭,那么一定是失败的。

代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h> #include <iostream> #include <string.h> #include <stdlib.h> #include <algorithm> #include <stack> #include <queue> using namespace std; #define LL long long struct Node { int id, def, add; friend bool operator < (Node a, Node b) { return a.def > b.def; } }; bool g[1009][1009]; int cnt[1009]; vector<Node > v[1009]; bool vis[1009]; int n, m, k; void init() { memset(cnt, 0, sizeof(cnt)); memset(g, 0, sizeof(g)); memset(vis, 0, sizeof(vis)); for(int i=0; i<n; i++) v[i].clear(); } bool bfs() { priority_queue<Node> q; for(int i=0; i<v[0].size(); i++) q.push(v[0][i]); if(cnt[0] == 0) { Node t = {0, -1, 0}; q.push(t); } vis[0] = 1; while(!q.empty()) { Node t = q.top(); q.pop(); if(t.def == -1) { for(int i=0; i<n; i++) { if(!vis[i] && g[t.id][i] == 1) { vis[i] = 1; for(int j=0; j<cnt[i]; j++) q.push(v[i][j]); if(cnt[i] == 0) { Node x = {i, -1, 0}; q.push(x); } } } continue; } if(t.def < k) { k += t.add; if(--cnt[t.id] == 0) { t.def = -1; q.push(t); } } else return false; } return true; } int main() { int T; scanf("%d", &T); while(T--) { init(); scanf("%d%d", &n, &m); for(int i=1; i<n; i++) { int a, b; scanf("%d%d", &a, &b); g[a][b] = g[b][a] = 1; } scanf("%d", &k); for(int i=0; i<m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); Node t={a, b, c}; v[a].push_back(t); cnt[a]++; } if(bfs()) printf("Oh yes.n"); else printf("Good Good Study,Day Day Up.n"); } return 0; }

最后

以上就是现代过客最近收集整理的关于GDUT Krito的讨伐(bfs&&优先队列)的全部内容,更多相关GDUT内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部