Problem Description
坎格鲁斯普雷和袋鼠将军在游玩一款名叫“战争游戏”的游戏,在这款游戏中,坎格鲁斯普雷是进攻方,袋鼠将军是防守方。
游戏的地图可以抽象为一张有着 n 个节点的树。初始时,防守方的人物在 s 号节点。
游戏将会进行 10100 回合,在每一回合中,游戏的流程如下:
首先,进攻方会选择一个节点 p ,作为轰炸中心,并对防守方进行“轰炸预告”,如果在回合结束时防守方所在的节点 t 与轰炸中心 p 的距离**不超过**轰炸半径 r1 ,那么防守方的人物将会被炸死,此时游戏结束,进攻方获胜。之后 防守方可以操纵他的人物移动到与当前位置的距离**不超过** r2 的节点上,然后回合结束。如果防守方的人物在回合结束时没被炸死,那么接着进行下一轮游戏,直到游戏轮次耗尽。若游戏轮次耗尽的时候防守方操纵的人物仍未死亡,那么防守方获胜,游戏结束。
作为袋鼠中的精英,坎格鲁斯普雷和袋鼠将军都是绝顶聪明的(即他们做出的操作都是当前盘面下的最优操作),那么在游戏结束时,谁将获胜?
Input
输入第一行一个整数 T ,表示测试数据组数。 (1≤T≤103)
每组测试数据,第一行四个整数 n , s , r1 , r2 。 (1≤n≤105,1≤s,r1,r2≤n)
之后 (n−1) 行,每行两个整数 ui , vi ,表示一条存在于树内的边。 (1≤ui,vi≤n)
数据保证 ∑n≤2×106 。
Output
对于每组测试数据,若坎格鲁斯普雷获胜,输出一行一个字符串 `Kangaroo_Splay` ;否则,输出一行一个字符串 `General_Kangaroo` 。每组测试数据的答案之间需换行。
树形dp模板题 (多种应用的一种 ~最长链~)判断能否不被炸到(也就是一直不被炸到)所以最长链够不够长就是判断的基本条件 求出来就轻松ac
#include<bits/stdc++.h>
using namespace std; using ll = long long;
using pii = pair<int, int>;
const int N = 1e5 + 10, mod = 1e9 + 7, INF = 0x3f3f3f3f;
int n,m,ans,r1,r2;
vector<pii> g[N];
void init() {
cin>>n>>m>>r1>>r2;
for(int i=0;i<=n;i++)g[i].clear();
for (int i = 0; i < n - 1; i++) {
int x, y, z;
cin >> x >> y;
g[x].emplace_back(y, 1);
g[y].emplace_back(x, 1);
}
return;
}
int dfs(int u, int pre) {
int d1 = 0, d2 = 0; //u的子树的最大长度,次大长度
for (auto i: g[u]) {
int nx=i.first;
int w=i.second;
if (nx == pre) continue;
int d = dfs(nx, u) + w;
if (d >= d1) {
d2 = d1;
d1 = d;
}
else if (d > d2) {
d2 = d;
}
}
ans = max(d1 + d2, ans);
return d1;
}
void solve() {
ans=0;
dfs(1, -1);
if(r1*2<ans&&r2>=2*r1+1){
cout<<"General_Kangaroo"<<endl;
}else{
cout<<"Kangaroo_Splay"<<endl;
}
return;
}
int main(void) {
int TT = 1;
cin>>TT;
for (int ii = 1; ii <= TT; init(), solve(), ii++) {}
return 0;
}

被折叠的 条评论
为什么被折叠?



