【1】 2-sat
2-sat是一个判定性问题。
典型事例:
【1】n个党派,每个党派恰有2个代表。
【2】 每个党派有且仅有一个参加委员会
【3】不和的两个代表(不属于同一党派)不能都属于委员会。
要判断是否存在这样的情况,如果存在输出一种可能情况。
算法大概也就是转化为图中两点的连通性问题。在此就不讲了。
主要是建模,模版现成可套。
一.确定为2-sat题目
从上述描述中我们可以归纳出几个特点:
【1】 有一个总数量限制,n派,且每派需两人组成
【2】 存在矛盾关系,且是在不同组(一个党派两个人看成一组)中
【3】 每派能只能出一人。
当我们看题时发现时判定性问题,且符合以上特点时,就可确认是2-sat.(当然这是最初步的,是否有更复杂的不清楚)
二.建模
那么也很显然要找出【1】N个派别,【2】确定每个派别的“2人”是什么【3】矛盾关系
例题:题目描述:
一天有N对结婚,在婚礼上在【1】开始Di段祝福或【2】结尾段祝福,只有一个祝福牧师,
判断该牧师是否可以【3】出现在每个婚礼上,不可同时出现在两个婚礼上,如果可以,
输出在每个婚礼上的起止时间。
第一步:确定问题
根据标志的【3】条,可以判断出该题属于2-sat问题。
第二步:转化模型
【1】显然对应于s,s`的为在【开始段祝福】和【在末尾祝福】
【2】在套模板之前显然需要【1】确立矛盾关系和【2】构图,也就是加边
分析:对于两个有相交的婚礼段,可能的重叠部分枚举一下也就4种:
既:【1】第一个的开始段与第二段的开始或结尾部分冲突
【2】第二个的开始段与第二段的开始或结尾部分冲突
四种情况具体如下:
(s1[i],t1[i])和(s1[j],t1[j])有交点,那么有i -> ^j;
(s1[i],t1[i])和(s2[j],t2[j])有交点,那么有i -> j;
(s2[i],t2[i])和(s1[j],t1[j])有交点,那么有^i -> ^j;
(s2[i],t2[i])和(s2[j],t2[j])有交点,那么有^i -> j;
剩下的就是套模版了。
2-sat的基本流程:
1.用求连通分量的方法确立有无解。
2.如果无解,输出。有解则缩点。
3.根据新图进行DFS,加盖完成时间戳F。
4.按时间戳F的先后顺序选取新图中的每个点,选取的同时删除对应的结点。
5.将属于被选取的点的连通分量中的所有点输出。
*(其中3,4步可改为拓扑排序+后序访问)