【学习笔记】CF1615G Maximum Adjacent Pairs
因为一个数 k k k只会贡献一次,所以启发我们用网络流或者图匹配之类的算法。
但是很遗憾,这道题是一般图匹配。
贪心告诉我们,对于一段连续的 0 0 0只有两端才会参与决策,更确切地说,设左右两端的数分别为 x x x和 y y y,分奇偶性讨论:
1.1
1.1
1.1 如果段的长度为奇数,那么新建一个点
z
z
z,将
z
z
z分别向
x
,
y
x,y
x,y连边。
1.2
1.2
1.2 如果段的长度为偶数,那么新建两个点,这两个点之间连边,同时其中一个向
x
x
x连边,另一个向
y
y
y连边。
不难证明答案就是这张图的最大匹配的大小。
这个转化其实不难。但是之所以比较难想到可能是出于数据范围。因为这样建图的点数是 O ( n ) O(n) O(n)的,无论怎么看都不是正解。
正解给我整无语了。考虑先不加两个点中间的那条边,然后跑二分图最大匹配,最后再加入这些边,跑带花树增广即可。
什么是带花树?对于一般图的增广算法,每次枚举一个未匹配点,设出发点为根,标记为黑点,接下来交错标记黑点和白点,不难发现白点到黑点这段边是匹配边。
假设当前点是 v v v,相邻点为 u u u,可以分为两种情况:
1.1
1.1
1.1
u
u
u未访问过,当
u
u
u是未匹配点,则找到增广路径,否则从
u
u
u的配偶找增广路。
1.2
1.2
1.2
u
u
u已经访问过,遇到标记黑点代表需要缩花(把奇环缩成一个黑点,同时将环上的白点加入队列),否则代表遇到偶环,跳过。

感觉图挺清楚的。整个过程都保证了交错树的结构,大体上和匈牙利算法类似。
但是问题来了,怎么找到具体的路径!经过大量手玩后,我直接绷不住了,唯一的感受是关键在于找到那条交错路径。换句话说一个奇环上有顺逆时针两种走法,但是我们要走交错路径对应的那个方向,这个简单嘛,建立一个后继链接 s u f suf suf就好。具体来说发现一定是先走一条非匹配边再走一条匹配边,这条非匹配边就是我们人为规定的后继链接 s u f suf suf。
复杂度据说是 O ( n 3 ) O(n^3) O(n3)。
但是感觉不如随机化匈牙利,所以代码我先咕着。

浙公网安备 33010602011771号