• Agc017_D Game on Tree


    传送门

    题目大意

    给定一棵树,$1$号节点为根,两个人轮流操作,每次选择一个根节点外的点,删掉它以及它的子树,不能操作者输,求两人均采用最优策略下先手胜利还是后手胜利。

    题解

    经典问题树上删边游戏,根据论文算法合集之《组合游戏略述——浅谈SG游戏的若干拓展及变形》,每个节点的$SG$值为其所有子节点$SG$值$+1$的异或和。

    判一号节点的$SG$值是否为$0$即可。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define M 200020
    using namespace std;
    namespace IO{
    	const int BS=(1<<20); int Top=0;
    	char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
    	char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
    	void flush(){fwrite(OT,1,OS-OT,stdout);}
    	void Putchar(char c){*OS++ =c;if(OS==fin)flush(),OS=OT;}
    	void write(int x){
    		if(!x){Putchar('0');return;} if(x<0) x=-x,Putchar('-');
    		while(x) SS[++Top]=x%10,x/=10;
    		while(Top) Putchar(SS[Top]+'0'),--Top;
    	}
    	int read(){
    		int nm=0,fh=1; char cw=Getchar();
    		for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
    		for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
    		return nm*fh;
    	}
    }
    using namespace IO;
    int n,fs[M],nt[M],to[M],tmp;
    void link(int x,int y){nt[tmp]=fs[x],fs[x]=tmp,to[tmp++]=y;}
    int DP(int x,int last){
    	int sg=0;
    	for(int i=fs[x];i!=-1;i=nt[i]) if(to[i]!=last) sg^=(DP(to[i],x)+1);
    	return sg;
    }
    int main(){
    	n=read(),memset(fs,-1,sizeof(fs));
    	for(int i=1;i<n;i++){int x=read(),y=read();link(x,y),link(y,x);}
    	puts(DP(1,0)?"Alice":"Bob");
    	return 0;
    }
  • 相关阅读:
    js事件
    增量
    文本文件输入(忽略行)
    当数据库的字段为date类型时候
    枚举的使用
    input输入框用el对数字格式化
    图片提交按钮各浏览器不兼容问题
    js对数字的校验
    时间控件
    ymPrompt消息提示组件4.0版 演示及使用简介
  • 原文地址:https://www.cnblogs.com/OYJason/p/9829960.html
Copyright © 2020-2023  润新知