造船(并查集)思路详解
造船
题目描述:
题目描述
小Y想要在虚拟世界里造船。最开始m个船的完成度全部都为0。小Y第i时刻可以在 a_i 和b_i两艘船中选择一艘让这艘船的完成度 。
由于国家政府是奇数控,所以所有偶数完成度的船只都将被摧毁,小Y想知道m时刻后能剩下来的船只最多有多少艘。
输入格式
第一行两个整数n和m
接下来m行,每行两个整数 a,b
输出格式
输出仅有一个整数,表示m时刻后能剩下来的船只最多有多少艘。
思路详解
没有想到正解,虽然很接近(最开始我也是两两连边画图做,但是想到二分图染色去了,但这里是及时发现是错的了)
其他题解说的很迷糊,这里我想了很久给出用并查集的详解
首先对于一个并查集内,
首先考虑不存在环的情况,此时肯定存在点数>边数,很显然的是我最多只能选边数个作为答案。
竟然是非环的话,那么肯定存在度数等于1的,贪心的话肯定先取这个,然后后面都没影响了。
然后像遍历dag一样拿取点,发现最终都能拿取,但是只能拿取max=边数
其实此时就是树的情况,答案都是n-1
当然可能出现点数<=边数的情况,说明有环的存在。
首先我尝试每个点都+1
这种操作肯定是可行的:考虑环上的点,利用边,在脑子里随便取一个点dfs来遍历,dfs便历顺序就是环上点的拿取顺序。
考虑非环上的点,由于是并查集,肯定是分为两种类型的点:
1.一个点连到环上去的类型,那么这个连到环上的边就肯定是选择非环上的那个点。
2.至于不连到环上的那种类型,其实就和非环图的想法一样了。
要是操作过后没有剩下操作次数(即开始时边数=点数)。
实际上就是个基环树,我们发现,基环树是肯定可以做到的且=n。
那么要是剩余有操作次数呢?
我假设先加入一条边,那么此时必定存在一个点将会被选择两次,等价于没被选择(偶数次)
竟然没被选择的话,那就可以看成原来链接他的两条边给删除了
显然,如果这个被选择两次的点在环上,这个环会被破坏,成为树
如果不在环上,我们可以换一种顺序安排边的选择,最终也达成删成树的情况
那我接着加入边,发现这个图又变成了基环树......
所以,这个图其实就是在树个基环树中反复横跳,最终这个连通块的答案肯定是n或者n-1
实在不会建议可以跟着上述过程手动模拟一下
证毕
至于代码实现,维护点数和边数的连通块就好了,用并查集,很EZ