zoukankan      html  css  js  c++  java
  • poj 3710 Christmas Game

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

    在一棵树的基础上将某个点扩充为一个环,每个环满足与原先的树只有一个公共点,且不存在两个环共用一条边

    在这样一张图上进行删边游戏

    将环与原先的树的公共点称作该环的根

    若环是偶环,则环的根SG=0,即先手面临一个独立的偶环必败。

    因为先手删去一条边后,该环断为两条链,一长一短,后手将长的那一条链变成与短的一样长即可获胜。

    若环是奇环,则环的根SG=1,即先手面临一个独立的奇环必胜。

    因为先手一定可以将环断为两条一样长的链。

    那么我们忽略掉偶环除根以外的点

    将奇环缩为环的根再加一条边一个点

    就转化成了树上删边游戏

    以下两图来自ccy1991911的博客

    http://blog.sina.com.cn/s/blog_51cea4040100h5j4.html

    缩成

    树上删边:https://www.cnblogs.com/TheRoadToTheGold/p/12207612.html

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    #define N 201
    #define M 1001
    
    int tot,front[N],to[M],nxt[M];
    int f[N];
    
    int id,dfn[N],low[N]; 
    int top,st[N];
    
    int bl[N],siz,tmp;
    
    int TOT,FRONT[N],TO[M],NXT[M];
    
    void add(int u,int v)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
    }
    
    void ADD(int u,int v)
    {
        TO[++TOT]=v; NXT[TOT]=FRONT[u]; FRONT[u]=TOT;
        TO[++TOT]=u; NXT[TOT]=FRONT[v]; FRONT[v]=TOT;
    }
    
    void tarjan(int u,int fa)
    {
        low[u]=dfn[u]=++id;
        st[++top]=u;
        int t;
        for(int i=front[u];i;i=nxt[i])
            if(i!=(fa^1))
            {
                t=to[i];
                if(!dfn[t])
                {
                    tarjan(t,i);
                    low[u]=min(low[u],low[t]);
                }
                else low[u]=min(low[u],dfn[t]);
            }
        if(low[u]==dfn[u])
        {
            siz=1;
            while(st[top]!=u) bl[st[top--]]=u,siz++;
            if(siz>1 && (siz&1)) ADD(u,st[top+1]);
            bl[st[top--]]=u;
        }
    }             
    
    void dfs(int u,int fa)
    {
        int t;
        for(int i=FRONT[u];i;i=NXT[i])
        {
            t=TO[i];
            if(t==fa) continue;
            dfs(t,u);
            f[u]^=(f[t]+1);
        }
    }
    
    int main()
    {
        int n,k,m,u,v,ans;
        while(scanf("%d",&n)!=EOF)
        {
            ans=0;
            for(int o=1;o<=n;++o)
            {
                scanf("%d%d",&m,&k);
                memset(front,0,sizeof(front));
                tot=1;
                for(int j=1;j<=k;++j)
                {
                    scanf("%d%d",&u,&v);
                    add(u,v);
                }
                memset(dfn,0,sizeof(dfn));
                tmp=0;
                memset(FRONT,0,sizeof(FRONT));
                TOT=0;
                for(int i=1;i<=m;++i)
                    if(!dfn[i]) 
                    {
                        id=top=0;
                        tarjan(i,0);
                    }
                for(int i=2;i<=tot;i+=2)
                    if(bl[to[i]]!=bl[to[i+1]]) ADD(to[i],to[i+1]);
                memset(f,0,sizeof(f));
                dfs(1,0);
                ans^=f[1];
            }
            puts(ans ? "Sally" : "Harry");
        }
        return 0;
    }            
    Christmas Game
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 3018   Accepted: 977

    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 tree, and removed the part of the tree which had already not connected with the root. A step shows as follows:

    Sally always moved first. Who removed the last part of the trees would win the game.

    After a while, they all figured out the best strategy and thought the game was too simple for them. Harry said, “The Christmas trees should have some gifts in them!” So Sally drew some gifts (simple polygons) in the initial trees:

    You may assume the initial picture is a tree with some simple polygons, in which each edge is involved in at most one polygon. We also know that every polygon has only one node involved in the main tree (the hanging point of the giftJ) .In every sub-tree (connected subgraph), there was one and only one node representing the “root”. According to these assumptions, following graphs will never appear:

    Sally and Harry took turns (Sally was always the first person to move), to cut an edge in the graph, and removed the part of the tree that no longer connected to the root. The person who cannot make a move lost the game.

    Your job is to decide who will finally win the game if both of them use the best strategy.

    Input

    The input file contains multiply test cases.
    The first line of each test case is an integer N (N<100), which represents the number of sub-trees. The following lines show the structure of the trees. The first line of the description of a tree is the number of the nodes m (m<100) and the number of the edges k (k<500). The nodes of a tree are numbered from 1 to m. Each of following lines contains 2 integers a and b representing an edge <a, b>. Node 1 is always the root.

    Output

    For each test case, output the name of the winner.

    Sample Input

    2
    2 1
    1 2
    4 4
    1 2
    2 3
    2 4
    3 4
    

    Sample Output

    Sally

    Hint

    The sample graph is

    Source

  • 相关阅读:
    C语言-第32课
    typeof和clamp
    C语言void*和*p的使用
    C语言二级指针和一级指针
    C语言结构体变量成员之指针变量成员的坑
    控制硬件三部曲
    C语言const char*使用
    jiffies是什么
    TPO3-1 Architecture
    相关关系|相关系数|线性关系|
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12207794.html
Copyright © 2011-2022 走看看