1169: Krito的讨伐
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 619 Solved: 102
Description
Krito终于干掉了99层的boss,来到了第100层。第100层可以表示成一颗树,这棵树有n个节点(编号从0到n-1),树上每一个节点可能有很多只怪物。 Krito现在在0号节点,现在它想要区清除这一层所有的怪物。他现在有atk大小的攻击力。只有当你的攻击力大于这只怪物的防御力时,你才可以打败他,同时每打败只怪物,你会获得一定的攻击力加成。一个节点可能存在着不止一只怪兽,你要打败这个节点的所有怪物才能可以从这个节点通过,请问他能不能完成这个任务?注意:不要求一次性杀光一个节点里面的所有怪物。
相关知识: 摘自维基百科
在计算机科学中,树(英语:tree)是一种抽象资料型别(ADT)或是实作这种抽象资料型别的数据结构,用来模拟具树状结构性质的资料集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
1.每个节点有零个或多个子节点;
2.没有父节点的节点称为根节点;
3.每一个非根节点有且只有一个父节点;
4.除了根节点外,每个子节点可以分为多个不相交的子树;
Input
第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
对于每一个测试样例,如果Krito能够清除所有的怪物,则输出“Oh yes.” 否则,输出“Good Good Study,Day Day Up.”
Sample Input
Sample Output
一直觉得这题有毒,用最后m是否等于0的方法写死活WA,然后换个方法重新写了下用从0开始拓展的方法写就可以过。
先上正确的代码:
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define INF 0x3f3f3f3f #define MM(x,y) memset(x,y,sizeof(x)) typedef pair<int,int> pii; typedef long long LL; const double PI=acos(-1.0); const int M=2010; const int N=1010; struct info { int to; int pre; }; struct mons { int d; int add; int cur; bool operator<(const mons &b)const { return d>b.d; } }; info E[M]; int head[N],cnt,ran[N]; int vis[N],n,m,atk; vector<mons> guaiwu[N]; priority_queue<mons>Q; void add(int s,int t) { E[cnt].to=t; E[cnt].pre=head[s]; head[s]=cnt++; } void init() { MM(head,-1); MM(vis,0); MM(ran,0); MM(vis,0); cnt=0; for (int i=0; i<N; i++) guaiwu[i].clear(); while (!Q.empty()) Q.pop(); } void findmons(const int &s) { if(guaiwu[s].empty()) return ; for (int i=0; i<guaiwu[s].size(); i++) Q.push(guaiwu[s][i]); guaiwu[s].clear(); } void dfs(const int &now) { for (int i=head[now]; ~i; i=E[i].pre) { int v=E[i].to; if(!vis[v]) { vis[v]=1; if(!ran[v]) dfs(v); else findmons(v); } } } int kill(const int &s) { if(!ran[s]) dfs(s); else findmons(s); while (!Q.empty()) { mons now=Q.top(); Q.pop(); if(now.d>=atk) return 0; else { atk+=now.add; ran[now.cur]--; if(!ran[now.cur]) dfs(now.cur); } } return 1; } int main(void) { int tcase,i,j,a,b,D,A,X; scanf("%d",&tcase); while (tcase--) { init(); scanf("%d%d",&n,&m); for (i=0; i<n-1; ++i) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } scanf("%d",&atk); mons t; for (i=0; i<m; i++) { scanf("%d%d%d",&t.cur,&t.d,&t.add); guaiwu[t.cur].push_back(t); ran[t.cur]++; } puts(!kill(0)?"Good Good Study,Day Day Up.":"Oh yes."); } return 0; }
修改N次仍然是WA的代码(不解题目既然保证了是一棵树不知道错的哪里):
#include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<stack> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; #define INF 0x3f3f3f3f #define MM(x,y) memset(x,y,sizeof(x)) typedef pair<int,int> pii; typedef long long LL; const double PI=acos(-1.0); const int N=1010; struct info { int cur; int d; int ATK; info(int c,int dd,int aa):cur(c),d(dd),ATK(aa){} info(){} bool operator<(const info &b)const { return d>b.d; } }; vector<info>mon[N]; vector<int>E[N]; priority_queue<info>kill; int ran[N]; int vis[N]; int n,m,atk; void reachble(const int &s) { int i,j; queue<int>Q; Q.push(s); while (!Q.empty()) { int now=Q.front(); Q.pop(); for (i=0; i<E[now].size(); i++) { int v=E[now][i]; if(!vis[v]) { vis[v]=1; if(!ran[v]) Q.push(v); else { for (j=0; j<mon[v].size(); j++) { if(mon[v][j].d!=-1) { kill.push(info(v,mon[v][j].d,mon[v][j].ATK)); mon[v][j].d=-1; } } } } } } } void init() { for (int i=0; i<N; i++) { E[i].clear(); mon[i].clear(); } while (!kill.empty()) kill.pop(); MM(vis,0); MM(ran,0); } bool cmp(const info &a,const info &b) { return a.d<b.d; } int main(void) { int i,j,tcase,x,y,d,a; scanf("%d",&tcase); for (int t=1; t<=tcase; t++) { init(); scanf("%d%d",&n,&m); for (i=1; i<n; i++) { scanf("%d%d",&x,&y); E[x].push_back(y); E[y].push_back(x); } scanf("%d",&atk); for (i=0; i<m; i++) { scanf("%d%d%d",&x,&d,&a); mon[x].push_back(info(x,d,a)); ran[x]++; } int flag=1; sort(mon[0].begin(),mon[0].end(),cmp); for (i=0; i<mon[0].size(); i++) { if(mon[0][i].d>=atk) { flag=0; break; } else { atk+=mon[0][i].ATK; --m; --ran[0]; } } if(!flag) { puts("Good Good Study,Day Day Up."); continue; } vis[0]=1; reachble(0); while (!kill.empty()) { info now=kill.top(); kill.pop(); if(now.d>=atk) break; atk+=now.ATK; --m; if(--ran[now.cur]==0) reachble(now.cur); } puts(m?"Good Good Study,Day Day Up.":"Oh yes."); } return 0; }