zoukankan      html  css  js  c++  java
  • HDU 1524 A Chess Game【SG函数】

    题意:一个N个点的拓扑图,有M个棋子,两个人轮流操作,每次操作可以把一个点的棋子移动到它的一个后继点上(每个点可以放多个棋子),直到不能操作,问先手是否赢。

    思路:DFS求每个点的SG值,没有后继的点为必败点。

    注意搜索中初始化的问题。

    #include<stdio.h>
    #include<string.h>
    const int N=1111,M=N*N;
    struct node{
        int v,next;
    }e[M];
    int head[N],cnt,in[N],out[N],n,sg[N],p[N];
    void add(int u,int v){
        e[cnt].v=v,e[cnt].next=head[u];
        head[u]=cnt++;
    }
    int SG(int u){
        if(!out[u])    return sg[u]=0;
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(sg[v]==-1)    sg[v]=SG(v);
        }
        memset(p,0,sizeof(p));
        for(int i=head[u];i!=-1;i=e[i].next){
            p[sg[e[i].v]]=1;
        }
        for(int i=0;i<n;i++){
            if(!p[i]){
                return sg[u]=i;
            }
        }
    }
    int main(){
        int m,k,i,u,v;
        while(~scanf("%d",&n)){
            memset(head,-1,sizeof(head));
            memset(sg,-1,sizeof(sg));
            memset(in,0,sizeof(in));
            cnt=0;
            for(i=0;i<n;i++){
                scanf("%d",&k);out[i]=k;
                while(k--){
                    scanf("%d",&v);
                    add(i,v);in[v]++;
                }
            }
            for(i=0;i<n;i++){
                if(!in[i]){
                    SG(i);
                }
            }
            while(~scanf("%d",&m)&&m){
                int ans=0;
                while(m--){
                    scanf("%d",&u);
                    ans^=sg[u];
                }
                if(ans)    puts("WIN");
                else    puts("LOSE");
            }
        }
        return 0;
    }
  • 相关阅读:
    Java文件读取
    Java继承
    JAVA程序提示错误:需要class,interface或enum解决方法
    SQL 修改列名
    转 父表字表统计查询的sql练习
    powerdesigner12.5入门教程
    现实世界
    oracle添加联合主键
    hashtable的用法
    JQ 1
  • 原文地址:https://www.cnblogs.com/L-King/p/5768232.html
Copyright © 2011-2022 走看看