模拟62 题解
A. Graph
在树的情况下,答案是显然的。
一次dfs,尽量将子树内不同的边合并就可以了。
考虑非树的情况,可以生成一棵树。
将非树边任意加在一个端点上,视作点权加一。
对于树上的每一个点,先考虑它的子节点,子节点的父边尽量在子节点处作连接节点使用。
如果子节点的父边还没有被使用,那么只能在父节点处使用。
同时将该节点的点权不断使用。
正确性是显然的,因为对于每一个联通块,都可以形成足够的边对。
B. Permutation
发现每次交换在位置上会变化很多,但是在值域上却只会变化 $1$。
这说明可以处理出数组 $pos$,使 $pos_{a_i}=i$,也就是说 $pos$ 是 $a$ 的逆置换,显然也有 $a_{pos_i} = i$。
将所有不能交换的点对建边,跑出最优的拓扑序就是最优解。
不能交换的点对的形式是简单的:$i < j, |pos_i - pos_j| < k$。
然而暴力建边是 $n^2$ 的,一个很好的性质是,在 $pos$ 的限制下,每个点建边区间范围是相同的。
所以每个 $i$ 只要分别向满足 $pos_j < pos_i$ 和 $pos_j > pos_i$ 两个条件的最小的 $j > i$ 建边就可以了。
有这样一个结论存在,想要最小化答案 $b$ 的拓扑序,等价于最大化 $b$ 的逆置换的反向拓扑序(反向边,从 $n$ 到 $1$ 求的拓扑序称为反向拓扑序),这个可以理解为不断把大的节点放在了后面,也就是尽量把小的放在了前面。
需要注意,最小化 $b$ 的逆置换的拓扑序的做法在一般情况下是错误的,但是在本题中因为一些特殊原因却是可以 AC 的。
本题中实际上是利用了特殊性质,因为会不断交换合法的点,使得不存在使原数组更小的情况。
具体证明见洛谷题解区,原题为 AGC001F。
C. Tree
答案为边权之和。
不妨考虑最优答案应当是怎样的。
每一条权值较小的边应当被尽量少的次数经过,所以应当尽量先取权值大的边。
想一想就可以知道:
最优答案一定不会大于边权之和。
因为对于任何一个排列,每条边至少会经过一次。
存在一种构造方式,构造出边权之和。
使最大边权所连的点入队,不断取出队中的点所连的最大边权,并将新点入队。
这样形成的排列,边权不断减小,所以每条边都被充分利用,所以是正确的。