AGC014D Black and White Tree

传送门

题意:
给出一棵有N个点的树。开始时,所有点都没被染色。两个人在这棵树上玩游戏。他们轮流操作:选择一个点,如果是先手操作,就把点涂成白色,否则涂成黑色。当所有点都被染色后,对于每一个与黑色点相邻的白色点,同时染成黑色。如果还有白点,先手胜,否则后手胜。两个人都采取最优策略,求出胜利者。

题解:
我们证明一下如果后手胜当且仅当这棵树是一个完全匹配。
先证充分性:先手选择一个点,后手选择该点的匹配即可。
再证必要性:如果不是完全匹配,那么一定有一个没匹配到的点,就让它为根。我们要找到父亲只有一个儿子的叶节点。如果没有,显然不是完全匹配,先手可以直接选择父亲,那么后手就GG了。然后先手选父亲,后手选儿子,否则先手一定会被后手染色。最后一定剩下一个点,让先手操作即可。
我也不知道我有没有把充分和必要写反QAQ

代码:

#include<cstdio>
#include<algorithm>
#define maxn 100005
using namespace std;
int n,ma[maxn];
struct node { int v; node *nxt; } edge[maxn*2],*head[maxn],*ncnt;
void addedge(int u,int v)
{
	ncnt++;
	ncnt->v=v,ncnt->nxt=head[u];
	head[u]=ncnt;
}
void dfs(int u,int fa)
{
	for(node *p=head[u];p;p=p->nxt)
	{
		int v=p->v;
		if(v==fa) continue;
		dfs(v,u);
		if(!ma[v])
		{
			if(ma[u]) { printf("First\n"); exit(0); }
			ma[u]=v,ma[v]=u;
		}
	}
}
int main()
{
	ncnt=&edge[0];
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		addedge(u,v); addedge(v,u);
	}
	dfs(1,0);
	printf("%s\n",ma[1]?"Second":"First");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值