2 SAT演算法學習筆記

2021-08-25 02:31:05 字數 1696 閱讀 1767

好像大概是這麼乙個東西,有一些集合,每個集合中有兩個元素(a

i,bi

) (ai

,bi)

,然後要求你從每乙個集合中選出乙個元素,但是同時對於集合元素的選取是有一些限制的,比如說什麼選了ai

a

i和aj

a

j必須選乙個,或者選了ai

a

i就必須選bj

b

j之類的。

然後我們發現上面所有的限制條件都可以轉化為一類,即選了ai

a

i就必須選擇bj

b

j這種。

然後解決這種問題演算法就是建立乙個有向圖,對於選ai

a

i就必須選bj

b

j這種限制,我們在圖中從ai

a

i連向bj

b

j,同時我們發現如果選aj

a

j也必須選bi

b

i,所以在圖中從aj

a

j連向bi

b

i。不難發現這個圖有對稱性。

對於這個有向圖,如果從ai

a

i可以到達bi

b

i,那麼ai

a

i一定是不可以選的,那麼根據有向圖的傳遞性以及這個圖本身的對稱性,那麼我們發現只有當ai

a

i和bi

b

i在同一強連通分量中是才有可能是無解的。

於是我們可以把圖建出來之後縮強連通分量,然後判斷一下有沒有無解的情況,如果有解的話就直接按照拓撲序的逆序選擇每個集合內的元素。

洛谷模板:

#include

#define rep(i,a,b) for(int i=a;i<=b;++i)

typedef

long

long ll;

using

namespace

std;

void file()

template

void read(t &_)

while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();

_=__*mul;

}const

int maxn=1e6+10;

int n,m;

int beg[maxn<<1],to[maxn<<1],las[maxn<<1],cnte=1;

int bel[maxn<<1],cnt_scc,low[maxn<<1],dfn[maxn<<1],cnt_dfn;

stack

stk;

void add(int u,int v)

void tarjan(int u)

else

if(!bel[to[i]])low[u]=min(low[u],dfn[to[i]]);

}if(dfn[u]==low[u])

}}void init()

}void work()

puts("possible");

rep(i,1,n)

}int main()

演算法學習筆記 2 SAT

sat 是適定性 satisfiability 問題的簡稱。一般形式為 k 適定性問題,簡稱 k sat。而當 k 2 時該問題為 np 完全的。所以我們只研究 k 2 的情況。2 sat,簡單的說就是給出 n 個集合,每個集合有兩個元素,已知若干個 表示 a 與 b 矛盾 其中 a 與 b 屬於不...

2 SAT學習筆記

由對稱性解2 sat問題 2 sat解法 上面兩篇 很清楚的介紹了什麼是2 sat以及一些原理演算法 2 sat問題是圖論中乙個比較有意思的問題,重點是建圖,對於邊的意思,就是如果你選了i,就必須選j。2 sat問題有個很明顯的地方就是對於每個i,i包含兩個點,i表示選第乙個點,i 表示選第二個點,...

2 SAT學習筆記

2 sat問題指的是,給你若干個0 1變數。並給你一些限制,讓你求滿足這些限制的可行解 字典序最小的解 限制的種類包括以下幾種 1 a一定是1 2 a一定不是1 3 a,b至少有1個是1 4 a,b最多有乙個是1 5 a,b一定相同 6 a,b一定不同 一般思路是對於乙個變數,建立兩個變數 正,反 ...