Atcoder [AGC004F] Namori

这篇博客介绍了Atcoder AGC004F问题,即如何通过翻转相邻相同颜色节点来改变图中所有点的颜色。作者分析了树的性质,提出将问题转化为异或运算,并利用树上的匹配来解决。通过计算每个子树中点权和,确定是否存在解决方案。同时,讨论了奇偶环的情况,解释了如何判断和操作以达到目标颜色状态。文章最后给出了问题的代码实现。
摘要由CSDN通过智能技术生成

Description

现在给你一张N个点M条边的连通图,我们保证N−1≤M≤N,且无重边和自环。

每一个点都有一种颜色,非黑即白。初始时,所有点都是白色的。

“全”想通过执行若干次某种操作的方式,来将所有的点变成黑色。操作方式如下:

选择一对颜色相同的相邻的节点(存在边直接连接彼此),将它们的颜色反转。即若原来都是白色,则都变成黑色,反之亦然。

现在“全”想知道,他能否通过执行这种操作以达到目的。如果可以,他还希望步数尽可能的少。


Input

    第一行有两个正整数N和M(2≤N≤105,N−1≤M≤N)
    接下来M行,每行2个正整数a和b(1≤a,b≤N),表示每条边连接的两个点。

Output

    如果存在操作方案使得“全”能达到目的,请输出最少操作次数。
    否则,请输出−1  

Solution

首先树的点数不能是奇数。

可以看到翻转相邻两个颜色相同的点其实是一种反异或。
所以我们可以把原问题转为异或。

将原图二分图染色,可以翻转相邻两个颜色不同的点,要让全树的颜色反转。
原图翻转相邻两点的操作可以看作交换一条边的两个点,则这个问题变为通过交换相邻两点达成全树反色,于是可以建立一个黑点和一个白点的匹配。
这是一个模拟费用流的经典题目,即树上老鼠进洞。
设白点权为1,黑点权为-1,sum[i]为i子树中点权和。
则有 a n s = ∑ s u m [ i ] ans=\sum sum[i] ans=sum[i]
s u m [ r o o t ] ≠ 0 sum[root]\neq 0 sum[root]=0则无解。

稍微讲讲怎么来的:
这个问题为什么相当于老鼠进洞?
因为在交换x和y的翻转过程中经过的点为黑,白,黑,白…白
其实在把一个黑点转到y的过程中的第一次操作也把一个白点转到了x。
所以只需要求所有老鼠(黑点)到洞(白点)的最小答案即可。

关于老鼠进洞:(建议自己查或自己想)因为我压根没想讲清楚
我们考虑一条边到底会翻转多少次(不一定连续)。
叶子结点肯定要出去,所以起码一次。
我们每上去一层,都会加上子树根i到father[i]的边,相当于把未匹配的黑点上提。
可以看到其实在i的儿子的情况下已经碰到了i(son[i]和i的边已经加入)
因为1和-1交换只用一次,所以下层的1在这层会被这层的-1抵消而不会重复计算,这样就保证了答案正确,即每个sum[i]是加上i点与儿子之间的边以后新增的向上步数。

现在讨论奇环的情况:
其实跟树没有差别。
可以看到我们随便断开一条环上的边再黑白染色,断开的边一定是同色的,那么我们可以通过操作这条边使得原图两个白点变黑或两个黑点变白,那么就是可以让sum[root]不断加减2使得sum[root]变为0(可以将外面的点也变色,建议画图)
就判断一下奇偶性就好了。

偶环:
现在连接两个异色点了。
可以看到环之外的边的交换次数并不会发生变化,只需要考虑环上的点。
被砍掉的边提供了更快的路径。
懒得写了直接看这个吧:https://blog.csdn.net/WerKeyTom_FTD/article/details/78393489


Code

#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值