POJ.3710.Christmas Game(博弈论 树上删边游戏 Multi-SG)
\(Description\)
给定n棵"树",每棵"树"的节点可能"挂着"一个环,保证没有环相交,且与树只有一个公共点。
两人轮流从树上删边,删去一条边后,不与根相连的一部分会被移除。最后无法移动的人输。问谁能赢。
\(Solution\)
如果没有环,那就是典型的树上删边游戏
考虑环,没有共用边且与树只有一个交点,那这是一个从树上某点\(x\)连出最后又连回这个点的简单环。
删除环上一边后会形成两条链 -> Multi-SG
若环是一个奇环,那么删去一条边后剩下的两条链奇偶性相同,这个后继状态的异或和(SG值)一定不为1,所以环的SG值为1(后继SG值的mex)
若环是一个偶环,那么删去一条边后剩下的两条链奇偶性相反,这个后继状态的异或和(SG值)一定不为0,所以环的SG值为0(mex)
于是可以删去所有偶环,把奇环看做一条边,就成了树上删边游戏的模型了
**树上删边游戏结论:叶子节点的SG值为0;中间节点的SG值为其 所有子节点SG值+1 后的异或和 **
具体见这
注: 访问完节点后不要忘记出栈
有长度为2的环!
#include <cstdio>
#include <cctype>
#include <cstring>
#define gc() getchar()
const int N=105,M=505;
int t,n,m,Enum,H[N],to[M<<1],nxt[M<<1],sg[N],top,sk[N],vis[N];
//vis=0:未访问过 vis=1:访问过且不是某个环上的点(不考虑树上点) vis=-1:访问过且是某个环上的点
//对于vis[x]=-1的(环) 不能统计答案!
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v){
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum;
}
void DFS(int x,int f)
{
sk[++top]=x, vis[x]=1, sg[x]=0;
bool flag=0;
for(int i=H[x]; i; i=nxt[i])
if(to[i]==f && !flag) flag=1;//第一次连向父节点
else{
if(vis[to[i]]==1){//仅靠vis和传参的cnt解决不了环。。还是要用栈
int cnt=1,now=x;
while(now!=to[i])
++cnt, vis[now]=-1, now=sk[--top];
if(cnt&1) sg[to[i]]^=1;//奇环
}
else if(!vis[to[i]])
{
DFS(to[i],x);
if(~vis[to[i]]) sg[x]^=(sg[to[i]]+1);//环上的不能更新
}
}
if(~vis[x]) --top;//非环上的 及时出栈
}
int main()
{
while(~scanf("%d",&t))//number of sub-trees
{
int res=0;
while(t--)
{
memset(vis,0,sizeof vis),
memset(H,0,sizeof H), Enum=top=0;
n=read(),m=read();
for(int u,v,i=1; i<=m; ++i) u=read(),v=read(),AddEdge(u,v);
DFS(1,0), res^=sg[1];
}
puts(res?"Sally":"Harry");
}
return 0;
}/*
1 2 2 1 2 1 2
*/
POJ.3710.Christmas Game(博弈论 树上删边游戏 Multi-SG)的更多相关文章
- poj 3710 Christmas Game(树上的删边游戏)
Christmas Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1967 Accepted: 613 Des ...
- POJ 3710 无向图简单环树上删边
结论题,这题关键在于如何转换环,可以用tarjan求出连通分量后再进行标记,也可以DFS直接找到环后把点的SG值变掉就行了 /** @Date : 2017-10-23 19:47:47 * @Fil ...
- poj 3710 Christmas Game 博弈论
思路:首先用Tarjan算法找出树中的环,环为奇数变为边,为偶数变为点. 之后用博弈论的知识:某点的SG值等于子节点+1后的异或和. 代码如下: #include<iostream> #i ...
- POJ Christmas Game [树上删边游戏 Multi-SG]
传送门 题意: 有N 个局部联通的图.Harry 和Sally 轮流从图中删边,删去一条边后,不与根节点相连的部分将被移走.Sally 为先手.图是通过从基础树中加一些边得到的.所有形成的环保证不共用 ...
- 【HDU 3590】 PP and QQ (博弈-Anti-SG游戏,SJ定理,树上删边游戏)
PP and QQ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- codeforces gym #101161F-Dictionary Game(字典树+树上删边游戏)
题目链接: http://codeforces.com/gym/101161/attachments 题意: 给一个可以变化的字典树 在字典树上删边 如果某条边和根节点不连通那么这条边也删除 谁没得删 ...
- poj 3710 Christmas Game【博弈论+SG】
也就是转换到树形删边游戏,详见 https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html #include<iostream> ...
- POJ 3710 Christmas Game#经典图SG博弈
http://poj.org/problem?id=3710 (说实话对于Tarjan算法在搞图论的时候就没搞太懂,以后得找时间深入了解) (以下有关无向图删边游戏的资料来自论文贾志豪<组合游戏 ...
- POJ 3710 Christmas Game [博弈]
题意:略. 思路:这是个删边的博弈游戏. 关于删边游戏的预备知识:http://blog.csdn.net/acm_cxlove/article/details/7854532 学习完预备知识后,这一 ...
随机推荐
- spring mvc常用配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Fiddler模拟post四种请求数据
前言: Fiddler是一个简单的http协议调试代理工具,它界面友好,易于操作,是模拟http请求的利器之一. 在接口测试中,接口通常是get请求或者post请求.get请求的测试一般较为简单,只需 ...
- 统一异常处理@ExceptionHandler
异常处理功能中用到的注解是:@ExceptionHandler(异常类型.class). 这个注解的功能是:自动捕获controller层出现的指定类型异常,并对该异常进行相应的异常处理. 比如我要在 ...
- compile php with openssl on mac osx error 填坑
从源码手动编译 PHP 时出现如下错误: Default 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Undefined symbols for arch ...
- 使用console进行 性能测试 和 计算代码运行时间
原文:http://www.tuicool.com/articles/JrARVjv 对于前端开发人员,在开发过程中经常需要监控某些表达式或变量的值,如果使用用 debugger 会显得过于笨重,最常 ...
- winform(记事本--剪切复制等和打开)
- vue-swiper的使用
写博客不是我的爱好,只是人脑毕竟空间只有那么大,有时候会忘了,好记性不如烂笔头,所以通过博客记录点点滴滴,以后可以翻出来看. vue-awesome-swiper官网链接https://www.npm ...
- 升级 php composer 版本
在执行 composer update 时,报错 You made a reference to a non-existent script @php artisan package:discover ...
- hdu3486 ST表区间最值+二分
还是挺简单的,但是区间处理的时候要注意一下 #include<iostream> #include<cstring> #include<cstdio> #inclu ...
- poj3481 splaytree模板题
找不到错在哪里,先留着吧 /* splay是以键值排序的! 三个操作:1 a b,z增加键值为b的点,值为a 2,查询最大值 3,查询最小值 需要的操作:rotate,splay,insert,fin ...