强连通的那点事

 

•前言

  昨晚做了一套 CodeForces Div.3 的题,其中有一道题【CodeForces 1213F】,赤裸裸的强连通分量分解的题;

  题目大意就是给你两个数组 p,q ,分别存放 1~n 的某个全排列;

  让你根据这两个数组构造一个字符串 S,要求:

    (1)$\forall\ i\in [1,n-1]\ ,S_{p_{i}}\le S_{p_{i+1}}\ ,\ S_{q_{i}}\le S_{q_{i+1}}$;

    (2)字符串 S 至少包含 k 个不同的小写字母;

•知识支持

  1. 在有向图 G 中,如果任意两个不同的顶点相互可达,则称该有向图是强连通的。
  2. 有向图 G 的极大强连通子图称为 G 的强连通分支。
  3. 转置图的定义:将有向图G中的每一条边反向形成的图称为 G 的转置 GT
  4. 注意到原图和GT的强连通分支是一样的

•推荐资料

  [1]:挑战程序设计竞赛(第二版)4.3.1 强联通分量分解

•Korasaju算法求有向图强连通分支(by挑战程序设计竞赛)

  

•Korasaju算法模板

  Korasaju求有向图强连通分支.cpp

•CodeForces1213F(强连通分量分解+BFS)

  如何根据 Korasaju 解决文章开始抛出的问题呢?

  你会发现,根据题干要求:

    $\forall\ i\in [1,n-1]\ ,S_{p_{i}}\le S_{p_{i+1}}\ ,\ S_{q_{i}}\le S_{q_{i+1}}$;

  建立一个 $p_i$ 指向 $p_{i+1}$ , $q_i$ 指向 $q_{i+1}$ 的有向图;

  用 Korasaaju 算法计算出强连通分量的个数,假设为 t;

  那么,每个强联通分量中的元素都必须标记为同一个小写字母,也就是说最多会有 t 个不同的小写字母;

  如果 t < k,直接输出 "NO";

  反之,将这些强连通分量分解后形成的 DAG 按照入度升序排列;

  对于前 k 个强连通分量包含的元素,依次标记为 $'a'+i\ ,\ i\in [0,k-1]$;

  而对于后 t-k 个,因为题干要求的是 $\le$,所以后 t-k 个强连通分量包含的元素可以全部标记为 $'a'+k-1$;

  而这个可以通过 BFS 实现;

•Code

  CodeForces1213F.cpp

 

posted @ 2019-09-06 15:51  HHHyacinth  阅读(260)  评论(0编辑  收藏  举报