AtCoder Grant Contest 10.F 博弈

本文探讨了一种在树形结构中进行的博弈游戏,玩家在节点间移动并减少节点权值,目标是使对手无法移动。文章分析了游戏的必胜策略,包括先手玩家的最优行动路径和判断必胜位置的条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给定一棵树,每个节点有个权值,Alice和Bob轮流进行操作,给定游戏起点指针指向节点C。不断进行下述操作。

1.将当前节点权值-1,然后将指针从该节点移动到相邻节点,出现一方不能移动(即指针指向的节点权值为0)即为输。

思路:

两个性质:

1.先手只会往权值严格小于当前节点的地方走。不然对手只需要把棋子位置移回来就可以耗死对方。

2.若存在权值严格小的相邻节点i且sg[i]=0,则当前节点是必胜位置。

之后的细节就很好想啦~~

 

 1 #include"bits/stdc++.h"
 2 #define ci(x) scanf("%d",&x)
 3 #define cd(x) scanf("%lf",&x)
 4 #define cl(x) scanf("%lld",&x)
 5 #define pi(x) printf("%d\n",x)
 6 #define pd(x) printf("%f\n",x)
 7 #define pl(x) printf("%lld\n",x)
 8 using namespace std;
 9 const int N = 3e3 + 5;
10 int n;
11 int a[N];
12 vector<int> e[N];
13 int dfs(int u,int pre){
14     for(int i=0;i<e[u].size();i++){
15         int v=e[u][i];
16         if(v==pre) continue;
17         if(a[u]>a[v]&&!dfs(v,u)) return 1;//v为必败态点且权值小于u,u即为必胜态。
18     }
19     return 0;//必败态
20 }
21 int main() {
22     ci(n);
23     for(int i=1;i<=n;i++) ci(a[i]);
24     for(int i=1;i<=n;i++) e[i].clear();
25     for(int i=1;i<n;i++){
26         int x,y;
27         ci(x),ci(y);
28         e[x].push_back(y);
29         e[y].push_back(x);
30     }
31     for(int i=1;i<=n;i++) if(dfs(i,0)) printf("%d ",i);
32     puts("");
33     return 0;
34 }

 

转载于:https://www.cnblogs.com/mj-liylho/p/9649186.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值