POJ 3710

树的删边游戏。。

由于题目的特殊性,我们只需计算环的边数值。若为偶环,则直接把环的根节点置0。若为奇环,则留下一条边与根结点相连,并那它们的SG置0;

注意的是,两个点也可构成环,因为允许重边。所以,我们只需求点双连通分量,并判断分量中边的数量即可。然后DFS求树的SG值。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4
  5
  6 using namespace std;
  7
  8 const int N=110;
  9 const int M=1100;
 10 int n,m;
 11 struct {
 12     int v,next;
 13 }edge[M];
 14 struct {
 15     int u,v;
 16 }edge_stack[M],tmp;
 17 int dfn[N],low[N],index;
 18 int edge_top,tot;
 19 bool vis[N],vis_e[M];
 20 int head[N],sg[N];
 21
 22 void addedge(int u,int v){
 23     vis_e[tot]=false;
 24     edge[tot].v=v;
 25     edge[tot].next=head[u];
 26     head[u]=tot++;
 27 }
 28
 29 void tarjan(int u){
 30     int i,j,k,v,e;
 31     dfn[u]=low[u]=++index;
 32     for(e=head[u];e!=-1;e=edge[e].next){
 33         v=edge[e].v;
 34         if(dfn[v]==-1){
 35             vis_e[e]=vis_e[e^1]=true;
 36             edge_stack[++edge_top].u=u;
 37             edge_stack[edge_top].v=v;
 38             tarjan(v);
 39             low[u]=min(low[u],low[v]);
 40             if(dfn[u]<=low[v]){
 41                 int cnt=0;
 42                 do{
 43                     tmp.u=edge_stack[edge_top].u;
 44                     tmp.v=edge_stack[edge_top].v;
 45                     edge_top--;
 46                     cnt++;
 47                     vis[tmp.u]=vis[tmp.v]=true;
 48                 //    printf("edge=%d %d ",tmp.u,tmp.v);
 49                 }while(!(tmp.u==u&&tmp.v==v));
 50             //    printf("\n");
 51                 if((cnt&1)){
 52                     vis[tmp.u]=vis[tmp.v]=false;
 53                 }
 54                 else vis[tmp.u]=false;
 55             }
 56         }
 57         else{
 58             if(!vis_e[e]){
 59                 low[u]=min(low[u],dfn[v]);
 60                 if(dfn[u]>dfn[v]){
 61                     edge_stack[++edge_top].u=u;
 62                     edge_stack[edge_top].v=v;
 63                 }
 64             }
 65         }
 66     }
 67 }
 68
 69 int dfs(int u){
 70     int e,v;
 71     vis[u]=true;
 72     int ans=sg[u];
 73     for(e=head[u];e!=-1;e=edge[e].next){
 74         int v=edge[e].v;
 75         if(!vis[v]){
 76             ans^=(dfs(v)+1);
 77         }
 78     }
 79     return ans;
 80 }
 81
 82 int main(){
 83     int k,u,v;
 84     while(scanf("%d",&k)!=EOF){
 85         int ans=0;
 86         while(k--){
 87         edge_top=-1;
 88         scanf("%d%d",&n,&m);
 89         tot=index=0;
 90         for(int i=1;i<=n;i++){
 91             vis[i]=false; sg[i]=0;
 92             head[i]=dfn[i]=low[i]=-1;
 93         }
 94         for(int i=1;i<=m;i++){
 95             scanf("%d%d",&u,&v);
 96             addedge(u,v);
 97             addedge(v,u);
 98         }
 99         tarjan(1);
100         ans^=dfs(1);
101         }
102         if(ans) printf("Sally\n");
103         else printf("Harry\n");
104     }
105     return 0;
106 }

POJ 3710,布布扣,bubuko.com

时间: 2024-10-13 02:10:09

POJ 3710的相关文章

POJ 3710 Christmas Game#经典图SG博弈

http://poj.org/problem?id=3710 (说实话对于Tarjan算法在搞图论的时候就没搞太懂,以后得找时间深入了解) (以下有关无向图删边游戏的资料来自论文贾志豪<组合游戏略述--浅谈SG游戏的若干拓展及变形>) 首先,对于无向图的删边游戏有如下定理性质: 1.(Fushion Principle定理)我们可对无向图做如下改动:将图中的任意一个偶环缩成一个新点,任意一个奇环缩成一个新点加一个新边:所有连到原先环上的边全部改为与新点相连:这样的改动不影响图的SG值. 2.(

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

Christmas Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1967   Accepted: 613 Description Harry and Sally were playing games at Christmas Eve. They drew some Christmas trees on a paper: Then they took turns to cut a branch of a tre

POJ 3710 Christmas Game

Harry and Sally were playing games at Christmas Eve. They drew some Christmas trees on a paper: Then they took turns to cut a branch of a tree, and removed the part of the tree which had already not connected with the root. A step shows as follows: S

【POJ】【3710】Christmas Game

博弈论 贾志豪论文上的题目……题解请看论文 Orz了一下Hzwer 1 Source Code 2 Problem: 3710 User: sdfzyhy 3 Memory: 716K Time: 0MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //POJ 3710 9 #include<cstdio> 10 #include<cstring> 11 #include<iostream> 12 #defi

POJ【数论/组合/博弈论】

 POJ[数论/组合/博弈论]题目列表 POJ[数论/组合/博弈论]题目列表 原来的列表比较水,今天换了一个难一些的列表,重新开始做~ 红色的代表已经AC过,蓝色的代表做了但是还没过.这句话貌似在我空间里的每份列表里都有额. 博弈论 POJ 2234 Matches Game POJ 2975 Nim POJ 2505 A multiplication game POJ 1067 取石子游戏 POJ 2484 A Funny Game POJ 2425 A Chess Game POJ 29

Part.4【博弈论】

---恢复内容开始--- 不要问我为什么突然跳到Part.4,我懒得解释. 在蔡大神的论文+讲解和HZW的题库下,自己大概是明白什么是博弈论的皮毛了吧. 先说SG定理吧. 对于游戏中的状态,我们给每个状态定义一个必胜态和必败态.区别在于前者可以通过一次操作到达必败态,但后者无法做到(后者在一次操作后所能到达的状态全部都为必胜态) 接着引进SG函数,每个状态都有一个SG值,这个值由它所能到达的状态的SG值决定.(这里的所能到达的状态指的是经过一次操作能到达的状态,下同) SG值有以下性质: SG值

(转载)--SG函数和SG定理【详解】

在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质: 1.所有终结点是 必败点 P .(我们以此为基本前提进行推理,换句话说,我们以此为假设) 2.从任何必胜点N 操作,至少有一种方式可以进入必败点 P. 3.无论如何操作,必败点P 都只能进入 必胜点 N. 我们研究必胜点和必败点的目的时间为题进行简化,有助于

SG函数和SG定理【详解】

在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质: 1.所有终结点是 必败点 P .(我们以此为基本前提进行推理,换句话说,我们以此为假设) 2.从任何必胜点N 操作,至少有一种方式可以进入必败点 P. 3.无论如何操作,必败点P 都只能进入 必胜点 N. 我们研究必胜点和必败点的目的时间为题进行简化,有助于

组合游戏 - SG函数和SG定理

在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质: 1.所有终结点是 必败点 P .(我们以此为基本前提进行推理,换句话说,我们以此为假设) 2.从任何必胜点N 操作,至少有一种方式可以进入必败点 P. 3.无论如何操作,必败点P 都只能进入 必胜点 N. 我们研究必胜点和必败点的目的时间为题进行简化,有助于