这里的博弈就是类似于取石子的博弈是一样的就是对于每一个父亲节点而言的话他的sg值的话就是它的儿子的各个sg值得异或
这道题目有一个特殊点就是于地面相连的那一条边是不能够取的这样的话就是与第一个点相连的那些点的sg值的所有后继状态的
组合会出现最后的结果,下面的图是我偷窥的某一位大佬的但是实现的代码是我自己实现的,就是几个竹子交在了一起出现了我们讨论的树链,详解的链接
http://blog.sina.com.cn/s/blog_8f06da990101252l.html
6.3 是图6.2中的第二个图
最后的转化过程就是父亲节点的sg值就是儿子的sg值的异或
14 15
13 12 11
6 7 8 9 10
3 4 5
2
1
这个样的话就是对于12这个点而言的话就是15的sg=0加上1,sg[12]=1;
sg[11]=0,s[10]=(sg[12]+1)^sg[11]=3,其他的节点的sg值可以类似的求出来
下面是实现的代码
#include <bits/stdc++.h>
using namespace std;
#define rep(i,s,n) for(int i=s;i<=n;i++)
#define per(i,n,s) for(int i=n;i>=s;i--)
const int Max =1e4+10;
bool visited[Max];
int sg[Max];
vector <int> ma[Max];
void DFS(int s){
visited[s]=true;
int h=0;
int len=ma[s].size();
rep(i,0,len-1){
int to=ma[s][i];
if(!visited[to]){
DFS(to);
h^=(sg[to]+1);
}
}
sg[s]=h;
}
int main(){
int n;
scanf("%d",&n);
rep(i,1,n-1){
int u,v;
scanf("%d %d",&u,&v);
ma[u].push_back(v);
}
DFS(1);
int key=0;
int len=ma[1].size();
rep(i,0,len-1){
int to=ma[1][i];
key^=sg[to];
}
printf("最后的异或值-----%d\n",key);
return 0;
}