题目链接:https://vjudge.net/contest/299140#problem/A
密码:2019
题目大意:给你一棵树,让你涂色
Jolly有一个绿色标记,Emily有一个红色标记。Emily首先开始游戏,然后轮流转换。
在每个回合中, 如果该边具有一些(至少一个)未着色的单元并且可以仅使用自由边缘从根部遍历边缘,则玩家可以 对树的边缘的一个单元着色。如果边缘没有完全着色(可以是未着色的或部分着色的),则认为边缘是自由的。
如果是Emily轮到她,她就会找到这样一个边缘并使用红色标记为其中一个单位着色。
如果轮到Jolly,他会找到这样的边缘并用绿色标记为其中一个单位着色。
无法找到颜色边缘的玩家将失去游戏。
思路:
green博弈变形,对于都是1的就是green博弈SG[u]^=SG[v]+1;
对于大于1的边,偶数对其没有贡献,奇数有贡献,SG[u]^= SG[v]^(val[v]%2);
#include <bits/stdc++.h>
using namespace std;
struct node
{
int v, w, next;
}e[2005];
int head[2005];
int sg[2005], tot=-1;
void into()
{
tot=-1;
memset(head, -1, sizeof(head));
}
void add(int u, int v, int w)
{
tot++;
e[tot].v=v;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot;
}
int dfs(int u, int fa)
{
sg[u]=0;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(v!=fa)
{
dfs(v, u);
if(e[i].w==1)
{
sg[u]^=(sg[v]+1);
}
else
{
sg[u]^=(sg[v]^(e[i].w%2));
}
}
}
}
int main()
{
int T, CUT=0;
scanf("%d",&T);
while(T--)
{
CUT++;
into();
int n;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u, v, w;
scanf("%d %d %d",&u,&v,&w);
add(u, v, w);
add(v, u, w);
}
dfs(0, -1);
if(sg[0])
{
printf("Case %d: Emily\n",CUT);
}
else
{
printf("Case %d: Jolly\n",CUT);
}
}
return 0;
}