【NOIP2017提高A组冲刺11.3】机房比教室好多了

这是一个关于NOIP2017提高组的博弈问题,描述了一个两人石头游戏。游戏在一个有N个节点的树上进行,玩家轮流从当前节点取石头并移动到相邻节点。当无法执行操作时,玩家输掉游戏。题目要求找出所有使Takahashi获胜的起始点。分析表明,先手玩家不会走向权值更大的节点,因此可以通过DFS遍历,标记单向边来判断起始点是否为必胜策略。
摘要由CSDN通过智能技术生成

题目

Description

这里有一个N 个点的树, 节点从1 到N 编号, 第i 条边连接了ai 和bi.
一开始第i 个点上有Ai 个石头. Takahashi 和Aoki 会玩一个游戏.
首先, Takahashi 会选择一个出发点; 然后, 从Takahashi 开始, 他们会轮流进行如下操作:
• 首先, 从当前的点上拿走一个石头.
• 然后, 走到一个相邻的点上.
当一个玩家无法执行操作时, 他就输了. 请你找到所有可以让Takahashi 获胜的出发点.

Input

N
A1 A2 ::: AN
a1 b1 …
aN−1 bN−1

Output

按升序输出一行表示可以让Takahashi 获胜的出发点.

Sample Input

输入1:
3
1 2 3
1 2
2 3
输入2:
5
5 4 1 2 3
1 2
1 3
2 4
2 5
输入3:
3
1 1 1
1 2
2 3

Sample Output

输出1:
2
输出2:
1 2
输出3:
(输出为空)

Data Constraint

对于30% 的数据, N <=7;Ai <= 6;
对于60% 的数据, N <= 2000;
对于100% 的数据, 1 <= N <= 10^6, 1 <= ai, bi <= N; 0 <= Ai <= 10^9, 保证输入的是一棵树.

题解

这道题目的性质在仔细分析一下还是比较明显的
对于在某个局面下的先手,他显然不会往比当前点权值大的点走(因为对手可以走回来,他血亏)
那么这道题目就解决了,对于一个起始点,它只能够往比自己权值小的子树走,如果这些子树中有一个局面是先手必败的,那么这个起始点就是先手必胜的
在具体的实现中,我们可以直接从点1开始做一次dfs,因为只能往比自己小的点走,所以说实际上这个树的边是一些单向边,那么我们直接打个标记就好了、

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)

using namespace std;

const int maxn=1e6+5;

int fi[maxn],ne[maxn*2],dui[maxn*2],qc[maxn],fa[maxn];
int c[maxn];
bool bt[maxn],bq[maxn];
int i,j,k,l,m,n,x,y,z,now;

void add(int x,int y){
    if (fi[x]==0) fi[x]=++now; else ne[qc[x]]=++now;
    dui[now]=y; qc[x]=now;
}
void dfs(int x){
    int i=fi[x];
    bq[x]=true;
    bool bz=false;
    while (i){
        if (c[dui[i]]<c[x]){
            bz=true;
            if (bq[dui[i]]==false){
                fa[dui[i]]=x;
                dfs(dui[i]);
            }
            if (bt[dui[i]]==false) bt[x]=true;
        }
        i=ne[i];
    }
    if (bz==false) bt[x]=false;

}
int main(){
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    scanf("%d",&n);
    fo(i,1,n) scanf("%d",&c[i]);
    fo(i,1,n-1){
        scanf("%d%d",&x,&y);
        add(x,y); add(y,x);
    }
    fo(i,1,n){
        if (bq[i]==false) dfs(i);
        if (bt[i]==true) printf("%d ",i);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值