POJ 3710 Christmas Game (Tarjan求连通分量+树形博弈删边游戏)
来源:互联网 发布:诸暨市行知小学座机 编辑:程序博客网 时间:2024/06/03 08:10
转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题目:有多棵树进行删边博弈,注意这里的”树“可能存在环,形状也许是非常诡异的。
我们利用The Fusion Principle:任何环内的节点可以融合成一点而不会改变图的sg值。(下面我们称它为融合原则)
我们会发现,拥有奇数条边的环可简化为一条边,偶数条边的环可简化为一个节点。
在这一步中很明显要求我们能找到图中的环,而且判断环中节点的个数,进行处理。
利用Tarjan算法找出强连通分量,毕竟不是搞图论的,现学现用。。。理解不深
可能出现重边,对于重边的处理是,如果两点间有偶数条边,则当作偶数环处理,将其化为一个点,否则保留。
将图转化成我们所要的树之后,便是经典的删边游戏了。
叶子节点的SG值为0;中间节点的SG值为它的所有子节点的SG值加1 后的异或和。
最后把多棵树一起做 一次NIM便完成。
#include<iostream>#include<cstdio>#include<ctime>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#define C 240#define TIME 10#define inf 1<<25#define LL long longusing namespace std;vector<int>edge[105]; //邻接表int mat[105][105]; //存放边的数量int low[105],dfa[105]; //Tarjan参量int s[105],top; //堆栈bool instack[105];bool vis[105]; //在Tarjan找环之后,把不需要的点标记掉void Tarjan(int u,int pre,int depth){ low[u]=dfa[u]=depth; s[top++]=u; instack[u]=true; for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; if(v==pre&&mat[u][v]>1){ //判断重边 if(mat[u][v]%2==0) vis[u]=true; continue; } if(!dfa[v]){ Tarjan(v,u,depth+1); low[u]=min(low[u],low[v]); } else if(v!=pre&&instack[v]) low[u]=min(low[u],dfa[v]); } if(dfa[u]==low[u]){ int cnt=1; top--; while(s[top]!=u){ vis[s[top--]]=true; cnt++; } if(cnt&&(cnt&1)) //如果节点为奇数,则保留一个点,包括u,也就是两个点,保留一条边 vis[s[top+1]]=false; }}int get_sg(int u,int pre){ int ret=0; for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; if(!vis[v]&&v!=pre) ret^=(1+get_sg(v,u)); } return ret;}int main(){ int k,n,m; while(scanf("%d",&k)!=EOF){ int ret=0; while(k--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) edge[i].clear(); memset(mat,0,sizeof(mat)); memset(low,0,sizeof(low)); memset(dfa,0,sizeof(dfa)); memset(instack,false,sizeof(instack)); memset(vis,false,sizeof(vis)); top=0; while(m--){ int u,v; scanf("%d%d",&u,&v); mat[u][v]++; mat[v][u]++; edge[u].push_back(v); edge[v].push_back(u); } Tarjan(1,-1,1); ret^=get_sg(1,-1); } puts(ret?"Sally":"Harry"); } return 0;}
- POJ 3710 Christmas Game (Tarjan求连通分量+树形博弈删边游戏)
- poj 3710 Christmas Game (树形删边游戏)
- POJ 3710 Christmas Game(Tarjan+博弈SG函数)
- [删边游戏] POJ 3710 Christmas Game
- POJ 3710 Christmas Game 无向图删边 经典的删边游戏 Tarjan缩点
- poj3710 Christmas Game 无向图 tarjan 连通分量
- 【POJ3710】Christmas Game 博弈 有限制的图上删边游戏(树形删边游戏进化1)
- POJ 3710 Christmas Game 树上删边博弈,压缩环
- poj 3710 Christmas Game(博弈 无向图删边游戏)
- POJ 1236 (Tarjan求强连通分量)
- [POJ3710]Christmas Game(博弈树的删边游戏)
- tarjan求强连通分量
- tarjan 求强连通分量
- POJ2186(tarjan求连通分量)
- tarjan求极大连通分量
- tarjan求强连通分量
- Tarjan求强连通分量
- tarjan求强连通分量
- C#调用C++Dll封装时遇到的一系列问题
- TCustomADODataSet组件的一些错误
- C# ThreadPool 的改进
- 自动化测试新途径- 上帝之眼 sikuli
- XML
- POJ 3710 Christmas Game (Tarjan求连通分量+树形博弈删边游戏)
- Hibernate 常见异常处理(转帖)
- 系统环境变量何时生效的 分析调查报告
- 字节对齐的规则
- 双系统中默认启动项无法更改为windows,不想用linux,用如下的方法修复mbr来默认从windws启动
- vc int to string
- java解析string类型的xml
- Floyd算法
- C#时常需要调用C++DLL