2 Sat模板詳解

2021-08-18 16:59:19 字數 2396 閱讀 1003

這幾天看了一下2-sat,因為有tarjan以及拓撲排序等等的知識基礎,還是比較好理解的,我看到的有兩個模板,乙個是時間複雜度為o(nm),另乙個時間複雜度為o(m),但是第二種存在一種侷限,他只是能求解隨機的解,但是如果要是求解字典序最小的解,只能使用第一種解法.......

我們就用乙個例子來看一下第乙個模板: hdu 1814

題目意思:有2*n個人,每兩個人一組(1-2一組,3-4一組),兩組中只能選擇其中乙個,同時又m對人有矛盾,有矛盾的人不能同時別選擇,有解的話,我們就輸出字典序最小的一組解,沒有解輸出"nie"

題目解析:我們比如一組人1-2,另一組3-4,我們1和3有矛盾,那麼我們如果選擇1的話,只能選擇4,如果選擇3的話,我們只能選擇2,那麼我們可以建圖將這樣必須的點之間連起來,那麼我們就可以直接通過dfs求解答案就可以,不存在解的情況就是:一組中的兩個人同時被選擇

#include #include #include #include using namespace std;

const int maxn = 20020;

const int maxm = 100010;

//當要求求解最小字典序的時候,我們只能用時間複雜度為o(nm)的這個演算法

struct edge

edge[maxm];

int head[maxn],tot;

void init()

void add_edge(int u,int v)

bool vs[maxn];//染色標記,true表示選擇

int stact[maxn],top;

bool dfs(int u) //我們要對u進行染色

bool twosat(int n)

}return true;

}int main()

if(twosat(2*n)) //判斷

else

printf("nie\n");

}return 0;

}

現在我們看一下第二種演算法:poj3648

現在還只是能當模板先用著,這個題中我們知道新郎和新娘是不能在同一邊的,我們要選擇的是新郎一遍的情況,所以答案中一定要包含新郎,我們要怎樣新增這個條件呢,我們就在0和1之間加一條邊,因為這個邊的含義是選了0之後必須要選1,那麼我們要是選擇0的話,就一定會選1,然後1我們會產生矛盾,從而我們就新增了這個條件,但是為什麼要反向建邊,等對2-sat有了更深刻的理解之後會再更新的...

#include #include #include #include #include #include using namespace std;

/**縮點->判斷同一集合中的點是否在同一連通分量中,如果在就沒有答案

拓撲排序,染色,染有同一顏色的可以被安排在同一

**/const int maxn =1000;

const int maxm = 100;

int n,m;

struct edge

edge[maxn];

int head[maxm],t;

int low[maxm],dfn[maxm],vis[maxm],stact[maxm],index,tot;

int belong[maxm],num;

int fp[maxm],color[maxm],in[maxm];

vectorg[maxm];

void init()

void add_edge(int u,int v)//t邊的條數

void tarjan(int u)

else if(vis[v])

low[u] = min(low[u],dfn[v]);

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

while(u != stact[index+1]);

}}void dag()//重新建圖,反向建邊

}}void toposort()

for(int i = 0;i < g[p].size();i ++)

if(-- in[g[p][i]] == 0)

q.push(g[p][i]);

}}int main()

add_edge(0,1);//如果選擇了0就必須選擇1,那麼就矛盾了,所以0一定不會被選,選出來的就是新娘那邊的

for(int i =0 ;i < 2*n;i ++)

if(!dfn[i])

tarjan(i);

bool flag = false;

for(int i = 0;i < 2*n;i +=2)

else

}if(!flag)

printf("\n");

}else

printf("bad luck\n");

}return 0;

}

模板 2 SAT 問題 2 SAT

2 sat 問題 模板 有n個布林變數 x 1 x n 另有m個需要滿足的條件,每個條件的形式都是 x i 為true false或 x j 為true false 比如 x 1 為真或 x 3 為假 x 7 為假或 x 2 為假 2 sat 問題的目標是給每個變數賦值使得所有條件得到滿足。輸入格式...

模板 2 SAT 問題

2 sat問題主要解決的是一類二取一的問題.做法就是先建圖,然後跑tarjan,然後就判斷正負是否衝突,假如有衝突,就說明無解,否則就判斷哪個的序號大.話說我也不知道為什麼序號大就代表1.題幹 題目背景 2 sat 問題 模板 題目描述 有n個布林變數x1x 1x1 xnx nxn 另有m個需要滿足...

2 sat基礎詳解

大量引用 2 sat解法 by 華中師大一附中 趙爽 由對稱性解2 sat問題 great influence關於p4782 模板 2 sat 問題的題解。在此對原作者表示衷心的感謝 在實際的題目中,限制往往還有除了或以外的別的形式,這些限制也將在這篇文章中討論。先討論以下兩類限制的情況 1 若x ...