题目链接:http://codeforces.com/contest/876/problem/E
题意:现在我们想要让所有行的字典序升序排列,且对于每一种数字,我们可以采用一种变换,比如 x->x'
,所有加 '
的都比不加小,问是否可以找到一种变换使得原序列升序。
思路:
只要相邻两行满足升序则原序列升序。
于是我们考虑相邻的两行 a,b ,找到第一个 ai!=bi ,则这两个序列之间的大小由这两个字母来决定,
既然要升序,假如 ai<bi ,则此时已经满足升序的条件,选择 ai 则必须选择 bi ,选择 b′i 则必须选择 a′i ,连边 ai−>bi,b′i−>a′i。
假如 ai>bi ,要使原序列升序则必须选择 a′i,bi ,连边 ai−>a′i,b′i−>bi
然后运用tarjan输出解,我原以为要在拓扑排序的过程选择哪些color的块可以选,选完某一个color的块,就要把其他的对立的color块标记上不可选。实际上,根本不需要标记对立的color块不可选。可以证明在2-sat经过tarjan后的DAG中,两个对立的点(i * 2, i * 2 + 1)中拓扑序小的那个点必然可以选,以这种规则产生的方案一定合法。 而且tarjan的过程中就能把每个点的拓扑序顺便处理出来了,代码量就很短了。
代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
不知道这种套路后写出来的sb的代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include