广东工业大学2016校赛 Problem A: Krito的讨伐




链接:戳这里


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

相关知识: 摘自维基百科 


在计算机科学中,树(英语:tree)是一种抽象资料型别(ADT)或是实作这种抽象资料型别的数据结构,用来模拟具树状结构性质的资料集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点: 


1.每个节点有零个或多个子节点; 


2.没有父节点的节点称为根节点;


 3.每一个非根节点有且只有一个父节点; 


4.除了根节点外,每个子节点可以分为多个不相交的子树;
广东工业大学2016校赛 Problem A: Krito的讨伐_第1张图片
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
1
5 2
0 1
0 2
2 3
2 4
11
3 10 2
1 11 0
Sample Output
Oh yes.


思路:首先我们先用邻接表把树给建出来,接着num[]统计每个节点上有多少怪,我们用优先队列qu存当前能到的节点的所有怪(按怪的防御从小到大排),那么如果当前队列首位的怪不能被打死,则daydayup

如果可以打,那么节点的怪num[]--,当该节点的怪都打光的时候,bfs跑这个节点能到的节点,如果能到的节点有怪,全部存进优先队列,这里需要一个跳板,需要在没有怪的节点强行加怪node(i,0,0)  这样的话才能跑完所有的节点,输出yes


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int T,n,m,V;
int head[10100],tot,vis[10100],num[10100];
struct edge{
    int v,next;
}e[10100];
void Add(int u,int v){
    e[tot].v=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
struct node{
    int x,y,z;
    node(int x=0,int y=0,int z=0):x(x),y(y),z(z){}
    bool operator < (const node &a)const{
        return y>a.y;
    }
}s[1000100];
priority_queue<node> qu;
void init(){
    mst(head,-1);
    mst(num,0);
    mst(vis,0);
    tot=0;
    while(!qu.empty()) qu.pop();
}
void solve(){
    while(!qu.empty()){
        node now=qu.top();
        qu.pop();
        if(V>now.y){
            V+=now.z;
            num[now.x]--;
        }
        if(num[now.x] && V<=now.y){
            cout<<"Good Good Study,Day Day Up."<<endl;
            return ;
        }
        if(num[now.x]==0){
            for(int i=head[now.x];i!=-1;i=e[i].next){
                int v=e[i].v;
                for(int j=1;j<=m;j++){
                    if(!vis[j] && v==s[j].x){
                        qu.push(s[j]);
                        vis[j]=1;
                    }
                }
            }
        }
    }
    cout<<"Oh yes."<<endl;
}
int main(){
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            Add(u,v);
        }
        scanf("%d",&V);
        for(int i=1;i<=m;i++) {
            scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].z);
            num[s[i].x]++;
        }
        for(int i=0;i<n;i++){
            if(!num[i]){
                s[++m]=node(i,0,0);
                num[i]++;
            }
        }
        for(int i=1;i<=m;i++){
            if(s[i].x==0) {
                qu.push(s[i]);
                vis[i]=1;
            }
        }
        solve();
    }
    return 0;
}
/*
10
5 2
0 1
0 2
2 3
2 4
11
3 10 2
1 11 0

5 2
0 1
0 2
2 3
2 4
11
0 10 1
0 11 2

5 4
0 1
0 2
1 3
2 4
6
1 5 2
2 6 3
3 12 4
4 12 0

5 4
0 1
0 2
1 3
2 4
6
1 5 2
2 6 3
3 10 4
4 12 0

3 3
0 1
1 2
11
0 10 2
1 11 3
2 12 4
*/



你可能感兴趣的:(广东工业大学2016校赛 Problem A: Krito的讨伐)