P5801 game on a tree

题意:

一张无向图, (Alice)选择从某处开始放一个棋子,然后 (Bob)(Alice) 依次移动这个棋子,但是不能走到到过的地方,无法操作者败。

假如做过P1623,可能会联想到要找树的匹配

分类讨论

假如树是完美匹配的,后手只要走先手的完美匹配点即可,先手会失败

树没有完美匹配,找出树的最大匹配((1,2),(3,4)),假如先手从一个没在最大匹配的点开始,后手不可能再走到一个没有在最大匹配的点,先后手转换

(f_x)表示(x)子树中多少点没有匹配即可

struct edge{int to,next;}e[N<<1]; int head[N],tot,f[N];
inline void add(int u,int v){
	e[++tot] = (edge){v,head[u]}; head[u] = tot;
}
void dfs(int x,int fa){
	f[x] = -1;
	for(int i = head[x];i;i = e[i].next){
		int v = e[i].to;
		if(v == fa) continue;
		dfs(v,x); f[x] += f[v];
	}
	if(f[x] < 0) f[x] = -f[x];
}
int main(){
	int n;scanf("%d",&n);int u,v;
	for(int i = 1;i < n;++i){
		u = read(); v = read();
		add(v,u); add(u,v);
	} dfs(1,0);
	puts(f[1] ? "Alice" : "Bob");
}
原文地址:https://www.cnblogs.com/shikeyu/p/13821539.html