首页 > 其他分享 >P8347 「Wdoi-6」另一侧的月 题解

P8347 「Wdoi-6」另一侧的月 题解

时间:2024-07-29 19:30:18浏览次数:6  
标签:结点 子树 int 题解 截取 P8347 奇点 Wdoi 偶点

P8347 「Wdoi-6」另一侧的月 题解

第一次自己思考出来紫题,题解纪念一下。


下面为大家讲解如何一步步推到最终结论:


首先,原树没有根,不妨设它的根为 \(1\),将它转化成有根的,便于操作。

为了方便描述,我们称将一个非根节点的点的父亲删去,保留含这个点的连通块这个操作为截取操作(就是保留一棵子树);相反,若是将一个非根节点的点删去,保留含这个点父亲的连通块,我们就称之为删除操作(就是把一棵子树丢掉)。

另外,我们称一个有偶数个儿子的节点为偶点,奇数个儿子的点为奇点。注意:所有叶子结点都算偶点。


我们可以先看深度为 \(2\)(根节点深度为 \(1\),下同)的树(菊花图,也就是特殊性质 \(A\))。容易发现,你肯定不能删根节点,那么就只能一个个删叶子结点。然后就能得出:如果有奇数个叶子结点,那么先手必败,偶数个叶子结点相反。

显然,如果原树有一个点所有儿子都是叶子结点,且这个点是偶点,那我们肯定不能将这个点的子树截取下来(不然就成了偶数个叶子结点的菊花图了,后手必败)。

而且我们还可以得出一个重要结论:如果原树有一个点所有儿子都是叶子结点,且这个点是奇点,那么先手一定可以直接把这个点的子树截取下来,那么后手就成为这个菊花图的先手,必败。所以如果有这么样的一个点,先手就必胜。所以,我们中途也一定要保证不能出现这种点,即如果原图没有这种点,中途就不能删任何叶子结点


接着,我们将深度推广为 \(3\)(这里假设只有深度为 \(3\) 的点才叫叶子结点,或者假设每个深度为 \(2\) 的点都有至少一个儿子)。显然,不能删叶子结点, 也不能保留一棵子树,那就只能一棵棵地删去子树。也能得出和菊花图类似的结论:如果根节点为奇点,先手必败,偶点相反。

所以像菊花图一样,如果能找到个根节点为奇点的这种子树,那么截取下来,先手必胜;否则就不能截取,也不能删这棵子树中任何一个结点(不然别人就可以截取下来获胜)。

继续,若深度为 \(4\),如果树中有上述的这种子树的话(也就是除根结点外所有点都是偶点,当然树的深度是小于等于 \(3\) 的),那么直接截取,否则只能一个个删深度为 \(2\) 的点的子树,同样,如果根节点为奇点,先手必败,偶点相反。

关键来了:我们可以以此类推下去,如果一棵子树的结点全是偶点(下称全偶图),那么我们就不能删其中任何一个结点,也不能截取这种树。如果有一个结点的所有儿子的子树都是全偶图,但这个点是奇点,那么只能一个个删它的儿子,最后先手必败。

得到上述结论后就好办了,如果真的有一个结点的所有儿子的子树都是全偶图,但这个点是奇点的话,那么直接将这个点截取下来,那么你就赢了(可以证明这种点一定存在,除非整个图就是一个全偶图,此时只需要删除一个深度为 \(2\) 的结点的子树即可)。但如果原树的根结点就是这种结点的话,你就输了(就相当于出题人把这种树给了你)。

所以结论就是,如果根结点是奇点,其它点是偶点,那么先手必败,否则必胜。


代码就非常简单了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define ll long long
using namespace std;
const int N = 1e5+5;
bool vis[N],b;
int siz[N],t,n;
vector<int> v[N];
void dfs(int x)
{
	vis[x] = 1;
	for(int i = 0;i < v[x].size();i++)
	{
		int nw = v[x][i];
		if(!vis[nw]){dfs(nw);siz[x]++;}
	}
	if(x!=1&&(siz[x]&1))b = 0;
}
int main()
{
	cin >> t;
	while(t--)
	{
		cin >> n;
		memset(vis,0,sizeof vis);memset(siz,0,sizeof siz);
		b = 1;for(int i = 1;i <= n;i++)v[i].clear();
		for(int i = 1;i < n;i++)
		{
			int x,y;scanf("%d%d",&x,&y);
			v[x].push_back(y);v[y].push_back(x);
		}
		dfs(1);puts(b&&(siz[1]&1)?"Luna":"Hifuu");
	}
	return 0;
}

\(5.16 :\) 突然发现一种简单的写法:如果根结点以外的点是偶点,那么加上父亲就相当于有奇数个点和它相连。那么后手赢当且仅当无根树所有点的度数都为奇数。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 1e5+5;
int s[N],n,t;
int main()
{
	cin >> t;
	while(t--)
	{
		memset(s,0,sizeof s);
		cin >> n;bool b = 0;
		for(int i = 1;i < n;i++)
		{
			int x,y;cin >> x >> y;
			s[x]++;s[y]++;
		}
		for(int i = 1;i <= n;i++)
			if(!(s[i]&1))b = 1;
		puts(b?"Hifuu":"Luna");
	}
	return 0;
}

标签:结点,子树,int,题解,截取,P8347,奇点,Wdoi,偶点
From: https://www.cnblogs.com/max0810/p/18330865

相关文章

  • CF538G Berserk Robot 题解
    Description有一个机器人,第\(0\)秒时在\((0,0)\)位置。机器人会循环执行一个长度为\(l\)的指令序列,每秒执行一个指令。指令有ULDR四种,分别代表向上/左/下/右移动一格。你不知道这个指令序列具体是什么,但是你知道\(n\)条信息,第\(i\)条信息为「第\(t_i\)秒时机器......
  • CF1634F Fibonacci Additions 题解
    CF1634FFibonacciAdditions题解传送门。题目大意:给定两个序列\(A\)和\(B\),每次一个可以选一个区间,并在区间的第\(i\)个数加上\(F_i\),其中\(F\)是斐波那契数列,你需要在每次询问结束时输出两个序列是否相等。可以先求一个序列\(C\)表示\(A\)和\(B\)每个位置的......
  • 剑指Offer题解合集
    剑指Offer题单及题解题目顺序为牛客上剑指Offer专题JZ3、数组中重复的数字分析可以直接对数组进行排序,通过判断首末数字大小来判断数字越界情况,注意数组为空的情况。发现\(0\leqnums[i]\leqn-1\),因此直接开一个数组判断是否有重复数字即可,返回第一个重复数字。代码......
  • 力扣题解2-两数相加
    问题的描述如下:分析过程:为了解决这个问题,我们需要逐位相加两个链表对应位置的值,并处理进位问题。具体步骤如下:初始化一个新的链表,用于存储结果。使用两个指针遍历两个输入链表,逐位相加,同时考虑进位。如果一个链表比另一个短,则将其视为0进行计算。处理最后可能存在的进位......
  • curl发送get和post请求时遇到&截断的问题解决
    get的parameter里带&被截断处理第一种是双引号括住 第二种是加反斜杠转义 post请求的body里有参数的value带了&curl-XPOSThttp://qa-ci.fuxi.netease.com:36800/job/xxxxx/xxxx--userxxxx:xxxxx-d token=popo -d"msg=cd/ssd/deployment_bash&&bashkill.b......
  • P10812 【MX-S2-T3】跳 题解
    题目分析考虑DP。显然当没有\(i\)连向\(i+1\)的边时,整个图是一个DAG,可以直接DP。所以我们DP要解决的唯一问题,就是考虑上\(i\)到\(i+1\)的边。考虑从\(n\)走到\(1\)的过程。当我们从\(i\)向前跳到\(j\)后,此时我们要么向前跳,要么往回走。又因为不能经过重复......
  • CF30E Tricky and Clever Password 题解
    考虑先贪心中间的回文串\(b\),因为这即使影响了两边的字符串,也不会改变最终的总串长。所以先使用manacher跑出来每个位置的最长回文半径。在考虑怎样找出最长的\(a\)和\(a'\)。可以二分答案,设此时答案为\(k\),找出的\(b\)串为\(s[l\dotsr]\),那么其合法的条件就是存在\(......
  • 关于网站安全狗卸载了仍然能拦截的问题解决
    关于网站安全狗卸载了仍然能拦截的问题解决如果你将所有safedog的文件删除的话,可能会导致Apache服务启动不了例如:这里没有提示相关安全狗的信息是因为我已经删除了Apache访问safedog的配置代码,只是提醒错误信息会如上图所示。导致这种原因的结果大概率是因为Apache的conf文件......
  • 题解:P4563 [JXOI2018] 守卫
    思路解法:区间DP。本题虽标上紫题,但黄队说了:“不要被颜色所吓倒。”易得,区间\([l,r]\)中最右端的亭子\(r\)一定会有保镖。先说一下可见性判断吧,只要\(l,r\)的连线的斜率大于\(p,r\)连成的线的斜率大,\(l\)即是可见的。如图,红线是\(r\)无法看到的,而蓝线是\(r\)可......
  • CF1178D Prime Graph 题解
    首先考虑一个问题:如果没有边数是素数的限制,应该怎么构造?这其实很简单,把原图连成一个环即可,每个点度数为\(2\)。接着考虑在原图上加边,注意到\(3\)也是个素数,所以每次可以任意选两个度数为\(2\)的点连边,此时仍然符合条件。这样加边最多可以加\(\left\lfloor\frac{n}{2}\rig......