「AGC010F」 Tree Game
「AGC010F」 Tree Game
切了一个 AGC 的题,很有精神。
于是决定纪念一下。
首先如果任意一个人在点 \(u\),他肯定不会向点权大于等于 \(a_u\) 的点走的,因为此时另一个人的最优策略显然是走回到点 \(u\),然后两个点的权值都减一,这样下去先输的肯定是前者。
然后一个人只会向点权小于 \(a_u\) 的地方走,根据这个性质判断一下:
- 如果当前这个人在点 \(u\) 没有路可以走,或是与 \(u\) 相连的点的权值均大于 \(a_u\),那么这个人肯定就输了。
- 如果某个人在点 \(u\),且存在一棵子树使得另一个人必败,那么这个人肯定就赢了。
按照这个东西从每个点出发 \(\text{DFS}\) 一下即可,时间复杂度为 \(O(n^2)\)。
而且感觉可能存在优于这个复杂度的解法?
我不会,欢迎大佬教我。
/*---Author:HenryHuang---*/
/*---Never Settle---*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e3+5;
int c[maxn];
vector<int> e[maxn];
int dfs(int u,int f,int now){
int flag=0;
for(auto v:e[u]){
if(v==f) continue;
if(c[v]>=c[u]) continue;
int tmp=dfs(v,u,now^1);
if(now==1&&tmp) return 1;
else if(now==0&&tmp==0) return 0;
}
if(flag==0){
if(now==1) return 0;
else return 1;
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n;cin>>n;
for(int i=1;i<=n;++i) cin>>c[i];
for(int i=1;i<n;++i){
int a,b;cin>>a>>b;
e[a].emplace_back(b);
e[b].emplace_back(a);
}
for(int i=1;i<=n;++i) if(dfs(i,0,1)) cout<<i<<' ';
return 0;
}
在繁华中沉淀自我,在乱世中静静伫立,一笔一划,雕刻时光。