zoukankan      html  css  js  c++  java
  • POJ Christmas Game [树上删边游戏 Multi-SG]

    传送门

    题意:

    有N 个局部联通的图。
    Harry 和Sally 轮流从图中删边,删去一条边后,不与根节点相
    连的部分将被移走。Sally 为先手。
    图是通过从基础树中加一些边得到的。
    所有形成的环保证不共用边,且只与基础树有一个公共点。
    谁无路可走谁输


    卡读题啊...$WA$了一节课了才发现是多组输入

    树上删边游戏:叶子节点的SG值为0;中间节点的SG值为它的所有子节点的SG值加1 后的异或和。

    一些节点多出去一个环?好像是Multi-SG唉!

    奇环的后继状态,两条奇偶性相同的链,异或和一定没有1

    偶环的后继状态,两条奇偶性不同的链,异或和一定没有0

    然后就是非常恶心的找环啦

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const int N=105,M=505;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m;
    struct edge{int v,ne;}e[M<<1];
    int cnt=1,h[N];
    inline void ins(int u,int v){
        e[++cnt]=(edge){v,h[u]};h[u]=cnt;
        e[++cnt]=(edge){u,h[v]};h[v]=cnt;
    }
    int vis[N],st[N],top,sg[N],mark[M<<1],circle[N];
    void dfs(int u){
        int &now=sg[u];//printf("dfs %d 
    ",u);
        if(vis[u]){
            int x=st[top--],cnt=1;
            while(x!=u) cnt++,circle[x]=1,x=st[top--];top++;
            if(cnt&1) now^=1;
            //printf("circle %d %d  
    ",u,cnt);
            return;
        }
        vis[u]=1; st[++top]=u;
        for(int i=h[u];i;i=e[i].ne) if(!mark[i]){ 
            mark[i]=mark[i^1]=1;
            dfs(e[i].v);
            if(!circle[e[i].v]) now^=sg[e[i].v]+1;
        }
        if(st[top]==u) top--;
    }
    int main(){
        freopen("in","r",stdin);
        int S;
        while(scanf("%d",&S)!=EOF){
            int sum=0;
            while(S--){
                n=read();m=read();
                for(int i=1;i<=n;i++) vis[i]=sg[i]=circle[i]=0; top=0;
                memset(mark,0,sizeof(mark));
                cnt=1;memset(h,0,sizeof(h));
                for(int i=1;i<=m;i++) ins(read(),read());
                dfs(1); sum^=sg[1];
                //printf("Sg ");for(int i=1;i<=n;i++) printf("%d ",sg[i]);puts("");
            }
            if(sum) puts("Sally");
            else puts("Harry");
        }
    }
  • 相关阅读:
    python基础(6)---set、collections介绍
    Vue Router滚动行为 scrollBehavior
    CSS expression属性
    定时器setTimeout实现函数节流
    axios封装
    vue项目结构
    搭建vue项目环境
    javascript参数传递中处理+号
    微信支付 chooseWXPay:fail
    微信支付get_brand_wcpay_request:fail
  • 原文地址:https://www.cnblogs.com/candy99/p/6548397.html
Copyright © 2011-2022 走看看