AT2376-[AGC014D]Black and White Tree【结论,博弈论】 正题

题目链接:https://www.luogu.com.cn/problem/AT2376


题目大意

给出(n)个点的一棵树,先后手轮流选择一个未染色的点染上白色(先手)/黑色(后手),如果最后有一个白色的点连接的都是白色的点则先手获胜,否则后手获胜。求是否先手必胜。

(1leq nleq 10^5)


解题思路

结论就是如果这棵树存在完全匹配那么就是后手必胜,因为后手可以每次选择先手选择的那个点的匹配点这样先手永远不可能获胜。

否则肯定存在一种方案使得存在一个叶子没有完全匹配,只要先手最后*这个叶子就好了。

时间复杂度:(O(n))


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
struct node{
	int to,next;
}a[N<<1];
int n,tot,ls[N],f[N][2];
void addl(int x,int y){
	a[++tot].to=y;
	a[tot].next=ls[x];
	ls[x]=tot;return;
}
void dfs(int x,int fa){
	f[x][0]=1;
	for(int i=ls[x];i;i=a[i].next){
		int y=a[i].to;
		if(y==fa)continue;
		dfs(y,x);
		f[x][1]&=f[y][1];
		f[x][1]|=f[x][0]&f[y][0];
		f[x][0]&=f[y][1];
	}
	return;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		addl(x,y);addl(y,x);
	}
	dfs(1,0);
	if(f[1][1])printf("Second");
	else printf("First");
	return 0;
}