http://poj.org/problem?id=3710

(说实话对于Tarjan算法在搞图论的时候就没搞太懂,以后得找时间深入了解)

(以下有关无向图删边游戏的资料来自论文贾志豪《组合游戏略述——浅谈SG游戏的若干拓展及变形》)

首先,对于无向图的删边游戏有如下定理性质:

1.(Fushion Principle定理)我们可对无向图做如下改动:将图中的任意一个偶环缩成一个新点,任意一个奇环缩成一个新点加一个新边;所有连到原先环上的边全部改为与新点相连;这样的改动不影响图的SG值。

2.(1)对于长度为奇数的环,去掉其中任意一个边之后,剩下的两个链长度同奇偶,抑或之后的SG值不可能为奇数,所以它的SG值为1;

    (2)对于长度为偶数的环,去掉其中任意一个边之后,剩下的两个链长度异奇偶,抑或之后的SG值不可能为0,所以它的SG值为0;

3.对于树的删边游戏,有如下定理:

          叶子节点的SG值为0;中间节点的SG值为它的所有子节点的SG值+1后的异或和。

所以对于这道题,用连通图的Tarjan算法找出环,然后删环,变成简单树,再进行Nim计算即可。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; vector<int> edge[105]; //邻接表
int belong[105][105]; //存放边的数量
int low[105],dfn[105];
int s[105],top; //堆栈
bool instack[105];
bool vis[105]; //用于标记不需要的点 void tarjan(int u,int pre,int depth)
{
low[u]=dfn[u]=depth;//depth是时间戳,即level
s[top++]=u;
instack[u]=true;
for(int i=0;i<edge[u].size();i++)
{
int v=edge[u][i];
if(v==pre&&belong[u][v]>1) //判断重边
{
if(belong[u][v]%2==0)//偶环
vis[u]=true;
continue;
}
if(!dfn[v])
{
tarjan(v,u,depth+1);
low[u]=min(low[u],low[v]);
}
else if(v!=pre&&instack[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
int cnt=1;
top--;
while(s[top]!=u)
{
vis[s[top--]]=true;
cnt++;
}
if(cnt&&(cnt&1)) //若节点为奇数,则保留两个点加一条边
vis[s[top+1]]=false;
}
} int getsg(int u,int pre)
{
int res=0;
for(int i=0;i<edge[u].size();i++)
{
int v=edge[u][i];
res^=(getsg(v,u)+1);
//叶子节点sg=0,其所有子节点的sg+1后进行异或
}
return res;
} void init(int m)
{
for(int i=1;i<=m;i++)
edge[i].clear();
memset(belong,0,sizeof(belong));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
memset(vis,0,sizeof(vis));
top=0;
} void add_edge(int u,int v)
{
belong[u][v]++;
belong[v][u]++;
edge[u].push_back(v);
edge[v].push_back(u);
} int main()
{
int n,m,k;
while(~scanf("%d",&n))
{
int res=0;
while(n--)
{
scanf("%d%d",&m,&k);
init(m); while(k--)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
tarjan(1,-1,1);
res^=getsg(1,-1);
}
if(res)
printf("Sally\n");
else printf("Harry\n");
}
return 0;
}

POJ 3710 Christmas Game#经典图SG博弈的更多相关文章

  1. poj 3710 Christmas Game【博弈论+SG】

    也就是转换到树形删边游戏,详见 https://wenku.baidu.com/view/25540742a8956bec0975e3a8.html #include<iostream> ...

  2. POJ 3710 Christmas Game [博弈]

    题意:略. 思路:这是个删边的博弈游戏. 关于删边游戏的预备知识:http://blog.csdn.net/acm_cxlove/article/details/7854532 学习完预备知识后,这一 ...

  3. poj 3710 Christmas Game(树上的删边游戏)

    Christmas Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1967   Accepted: 613 Des ...

  4. poj 3710 Christmas Game 博弈论

    思路:首先用Tarjan算法找出树中的环,环为奇数变为边,为偶数变为点. 之后用博弈论的知识:某点的SG值等于子节点+1后的异或和. 代码如下: #include<iostream> #i ...

  5. POJ 3710 Christmas Game

    知识储备: 解决办法(奇偶去环):   (1) 对于长度为奇数的环,去掉其中任意一个边之后,剩下的 两个链长度同奇偶,抑或之后的 SG 值不可能为奇数,所 以它的 SG 值为 1: (2) 对于长度为 ...

  6. POJ.3710.Christmas Game(博弈论 树上删边游戏 Multi-SG)

    题目链接 \(Description\) 给定n棵"树",每棵"树"的节点可能"挂着"一个环,保证没有环相交,且与树只有一个公共点. 两人轮 ...

  7. HDU 1848(sg博弈) Fibonacci again and again

    Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  8. POJ 3710 无向图简单环树上删边

    结论题,这题关键在于如何转换环,可以用tarjan求出连通分量后再进行标记,也可以DFS直接找到环后把点的SG值变掉就行了 /** @Date : 2017-10-23 19:47:47 * @Fil ...

  9. UVA12293 Box Game —— SG博弈

    题目链接:https://vjudge.net/problem/UVA-12293 题意: 两人玩游戏,有两个盒子,开始时第一个盒子装了n个球, 第二个盒子装了一个球.每次操作都将刷量少的盒子的球倒掉 ...

随机推荐

  1. windows Git安装

    git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目 一.Git下载 官网地址:https://git-scm.com/download/win,选择相应的版本即可 二.安 ...

  2. To the end

    身为一名初二狗的我也走过了半年.不管怎么说人生中也没有几个半年嘛.从九月到现在快四个月了,我也离中考越来越近了/郁闷/.但是还是要好好过唔.不过我想起这半学期还是挺充实的,至少没有浪费太多的时间.有些 ...

  3. hdu 1299 Diophantus of Alexandria(数学题)

    题目链接:hdu 1299 Diophantus of Alexandria 题意: 给你一个n,让你找1/x+1/y=1/n的方案数. 题解: 对于这种数学题,一般都变变形,找找规律,通过打表我们可 ...

  4. Listview右侧 IndexBar

    qq 好友聊天界面,右侧 IndexBar  A B C D ,点击跳转到相应的联系人名字 import android.content.Context; import android.graphic ...

  5. Makfile文件编写

    一.make是什么 GNU make是一个工程管理器,专门负责管理.维护较多文件的处理,实现自动化编译.如果一个工程项目中,有成百上千个代码源文件,若其中一个或多个文件进过修改,make就需要能够自动 ...

  6. excel 常用函数

    1.统计整列唯一值的数量 =sumproduct(1/countif(offset(A1,,,COUNTA(A:A)),OFFSET(A1,,,COUNTA(A:A))))

  7. Python学习笔记——基础篇【第六周】——hashlib模块

    常用模块之hashlib模块 用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法 import ...

  8. mysql中datetime和timestamp的区别

    原文地址:http://database.51cto.com/art/200905/124240.htm 相同 显示 TIMESTAMP列的显示格式与DATETIME列相同.换句话说,显示宽度固定在1 ...

  9. android 之 java环境部署

    上甲骨文公司官网下载最新的jdk http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-z ...

  10. [编码解码] Base64 编码换行和+号遍空格的处理

    Android自身带有Base64加密与解密的包,可以方便地加密密码方便传输. String base64Token = Base64.encodeToString(token.trim().getB ...