有一个简单的博弈问题:
现在有一颗 \(n\) 个点的树,每次询问后给出一个点连接的所有子节点。
Alice 和 Bob 在树上博弈。
Alice 和 Bob 每次可以将点向下移动一格。
如果到了叶子节点,便不再移动,交互库给出叶子权值。
Alice 希望选的数最大,Bob 反之。
求:到达的数最后是多少?
显然有 \(\mathcal O(n)\) 做法:
\[f(i,0) = \max_{v\in son_i} f(v,1) \]\[f(i,1) = \min_{v\in son_i} f(v,0) \]但是我们询问次数想要尽可能小。
若我们搜索到了一个点。
我们维护两个变量 \(\alpha,\beta\)。
\(\alpha\) 表示现在可以至少取到 \(\alpha\)。
\(\beta\) 表示现在走到该子树内可以取到的最大值。
最后 \(\alpha \ge \beta\) 时直接退出即可,因为显然不优。
int alpha_beta(int u, int alph, int beta, bool is_max) {
if (!son_num[u]) return val[u];
if (is_max) {
for (int i = 0; i < son_num[u]; ++i) {
int d = son[u][i];
alph = max(alph, alpha_beta(d, alph, beta, is_max ^ 1));
if (alph >= beta) break;
}
return alph;
} else {
for (int i = 0; i < son_num[u]; ++i) {
int d = son[u][i];
beta = min(beta, alpha_beta(d, alph, beta, is_max ^ 1));
if (alph >= beta) break;
}
return beta;
}
}
引用了 oi-wiki 上的代码。
标签:剪枝,int,max,beta,son,Beta,alpha,Alpha,alph From: https://www.cnblogs.com/WhisperingWillow/p/18400827