[XVI Open Cup GP of China] A. Graph Drawing
那确实是神仙题,阅读 jiangly 代码遂取之。
简要题意
给定一个点双联通的平面图,保证每个点的度数不超过 \(4\);具体地对于每个面将会按照逆时针顺序给出上面的顶点。现在要求把它画在无限大的网格上,要求边都平行于坐标轴,且彼此除了两端点外不接触。由于可能不能画出来,允许边进行任意的直角拐弯。求最少的总拐弯次数。
解法
点双联通的目的是防止一个点四条出边都在同一个面上这种恶劣情况的出现。
考虑最简单的合法面——长方形,发现它有四个拐弯点。一个拐弯点要么在某个给定的点上,要么在边上(此时有 \(1\) 的代价)。考虑一些更复杂的面,虽然此时拐弯点的总数可能变多了,但是我们考虑给它们这样分类:逆时针沿着环走,一个拐弯点是向左拐的还是右拐的。容易发现向左拐的点恰好比向右拐的点多 4 个。接下来观察点:考虑如果一个点有两条邻边(也就是有两个相邻面)则它要么在两个面中都不是拐点,要么在其中一个是左拐点,另一个是右拐点;而如果一个点度数为三,则它在其中恰好两个邻面成为左拐点;如果度数为四它在全部的四个邻面成为左拐点。边上的拐弯可以视作以 \(1\) 的代价新增一个二度点。此外,最外面一个额外加入的(无穷延伸的)面比较特别——它多出四个右拐点而不是左拐点。我们断言只需要确定了每个点和边对它周围的面的拐点贡献,就一定能得到一种合法嵌入方法。这个证明我不会,意淫一下就很对。
那么很自然的,想到使用网络流刻画这一过程:具体地,每个内部面必须接受 \(4\) 的流量,而最外面的面必须提供 4 的流量。一条边可以以 \(1\) 的代价在两个面之间传递流量;而一个二度点可以以 \(0\) 的代价传递。一个三度点向周围的三个面提供 \(2\) 的流量;一个四度点向周围 \(4\) 个面各自提供 \(1\) 的流量。这样的一个最小费用最大流答案即一组合法解。