码迷,mamicode.com
首页 > 其他好文 > 详细

SEERC 2019 F. Game on a Tree

时间:2020-04-02 10:34:45      阅读:312      评论:0      收藏:0      [点我收藏+]

标签:博弈   print   for   push   auto   无法   +=   vector   接下来   

题意:

给一棵树,先手可以任意选一个点染色,接下来每个人可以将当前点的一个祖先或一个孩子染色,一个点只能被染色一次,谁无点可以染色谁就输了。

解法

对于一个点,可以到达的点有所有祖先和所有孩子。如果u可以到达v节点,那么v节点显然也可以到达u节点。
此时我们可以考虑将树上博弈转化成图。n个节点,每个点与可到达的节点连边,就会形成一张图。
手玩几个例子,大概可以发现当最大匹配是完美匹配的时候后手必胜,否则先手必胜。下面给出证明。

1.最大匹配是完美匹配时,后手必胜。

因为完美匹配,所以n个点必可以分成n/2组,\((v_1,v_2),(v_3,v_4)...(v_{n-1},v_n)\),那么先手每选一个点,后手就选与之同组的一个点。那么先手必将在某一步无路可走。后手必胜。

2.最大匹配不是完美匹配时,先手必胜。

设最大匹配\(E={(v_1,v_2),(v_3,v_4)...(v_{k-1},v_k)}\)。那么先手选一个不在匹配内的点,会发生以下两种情况:
(1)后手选择匹配内的点。
此时先手如同1进行操作就可以必胜。因为如果后手在某一轮选择一个匹配外的点,例如在\(v_4\)后选择一个匹配外的点,我们就会发现\((v_a,v_1),(v_2,v_3)(v_4,v_b)\)是可达的,那么\({(v_a,v_1),(v_2,v_3)(v_4,v_b)...(v_{k-1},v_k)}\)就是一个更大的匹配,与假设不符。所以后手无法再次选择匹配外的点,游戏如1进行,先手此时必胜。
(2)后手也选择匹配外的点。
那么很显然,\((v_a,v_b)\)是可达的,可以加入最大匹配,与假设不符。不可能。
所以,最大匹配不是完美匹配时,先手必胜。

于是,题目就转换成了求由这棵树构成的图是否具有完美匹配。树DP即可。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5;
int f[maxn + 11];
vector <int> edge[maxn + 11];

void dfs(int x,int fa) {
	for (auto v : edge[x]) {
		if (v == fa) continue;
		dfs(v , x);
		f[x] += f[v];
	}
	if (f[x]) f[x] -= 1;
	else f[x] = 1;
}

int main(){
	int n;
	scanf("%d",&n);
	for (int i = 1; i < n; i++) {
		int u,v;
		scanf("%d %d",&u,&v);
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	dfs(1 , 0);
	if (!f[1]) printf("Bob\n"); else printf("Alice\n");
} 

SEERC 2019 F. Game on a Tree

标签:博弈   print   for   push   auto   无法   +=   vector   接下来   

原文地址:https://www.cnblogs.com/Embiid/p/12617850.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!