ch_g

ECUST_ACMer —— ch_g
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

凸多边形面积并 O(N^2 * logN)(2011年10月29日有修改)

Posted on 2011-10-17 16:31  ch_g  阅读(1877)  评论(11编辑  收藏  举报

 

  凸多边形面积并 复杂度O(N^2 * logN) (N为总边数)

  今天突然有人问我有关凸多边形面积并的算法,由于马上要去北京比赛了,就匆匆写个大概的算法流程。其中有很多细节和需要证明的地方都略过了(建议还是主要看代码吧),如果有什么不清楚或错误的地方还请指出。


  首先,先向AC大牛致敬,他的凸多边形面积并的算法给我帮助很大,让我学到了很多东西。

  AC大牛的博文:http://hi.baidu.com/aekdycoin/blog/item/fbe5a03232c71952ad4b5fcc.html

  这里凸多边形面积并的算法非本人原创,是参考Codeforces Round #83 DIV1 的 E题syntax_error的代码而学习到的。

  题目链接:http://codeforces.com/contest/107/problem/E

  代码链接:http://codeforces.com/contest/107/status/E

 

  syntax_error的算法思想类似于梯形剖分。

  主要想法就是把多边形的上下边界进行梯形剖分求面积,然后相减得到所求区域的面积


  预处理:将所有的凸多边形的点按照逆时针排列,并去除退化为线段或点的“凸多边形”。


      将所有凸多边形的有向边分为三类:向左、向右和垂直于x轴的。对应于下图中的蓝色边、红色边和黄色边。(黄色的边无视)

                 

  

  对于蓝色的边(计算面积的过程如下图)

 

         

 

   对于红色的边(计算面积的过程如下图)

      

 

 

  其实蓝色的边和红色的边的处理方法都是一样的,只要计算边“暴露在外”的部分到x轴的面积。 

  蓝色部分和红色部分面积相减后,可以发现两个凸多边形面积并的部分恰好计算了一次,而其他部分蓝色覆盖层数和红色覆盖层数相同(即下图中黑色边框部分)。

  其中的原因我就不细说了,大家可以自己体会一下。

      


处理出每条边所在直线,并去重(这里用方程y = k x + b kb来表示一条直线,方便去重和后续处理)。

      对于每条直线,需要求出它和每个多边形的交点,该直线和某多边形恰有两个交点时(其他情况不做处理),把两个交点对应x轴坐标处分别标上010表示进入某多边形内,1表示从多边形中出来。

 

 

 

  另外还要记录这条直线上被多边形的边覆盖的区域有哪些,与上面类似的,分别标记232表示进入某线段,3表示从线段中出来。

 

 

 

然后将标记过的坐标点排序,从小到大遍历,并且维护两个变量inctin表示在几个多边形内,ct表示被几条多边形的边覆盖)。当in == 0ct > 0时需要统计该梯形面积