模板 2 SAT 問題

2022-03-13 05:43:57 字數 1948 閱讀 5250

2-sat問題主要解決的是一類二取一的問題.做法就是先建圖,然後跑tarjan,然後就判斷正負是否衝突,假如有衝突,就說明無解,否則就判斷哪個的序號大...話說我也不知道為什麼序號大就代表1.

題幹:

題目背景

2-sat 問題 模板

題目描述

有n個布林變數x1x_1x1​~xnx_nxn​,另有m個需要滿足的條件,每個條件的形式都是「xix_ixi​為true/false或xjx_jxj​為true/false」。比如「x1x_1x1​為真或x3x_3x3​為假」、「x7x_7x7​為假或x2x_2x2​為假」。2-sat 問題的目標是給每個變數賦值使得所有條件得到滿足。

輸入輸出格式

輸入格式:

第一行兩個整數n和m,意義如體面所述。

接下來m行每行4個整數 i a j b,表示「xix_ixi​為a或xjx_jxj​為b」(a,b∈)

輸出格式:

如無解,輸出「impossible」(不帶引號); 否則輸出

"possible

"(不帶引號),下 一行n個整數x1x_1x1​~xnx_nxn​(xix_ixi​∈),表示構造出的解。

輸入輸出樣例

輸入樣例#

1: 複製31

1130

輸出樣例#

1: 複製

possible00

0說明1<=n,m<=1e6 , 前3個點卡小錯誤,後面5個點卡效率,由於資料隨機生成,可能會含有( 10010

0)之類的坑,但按照最常規寫法的寫的標程沒有出錯,各個資料點卡什麼的提示在標程裡。

題解:

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

#define duke(i,a,n) for(int i = a;i <= n;i++)

#define lv(i,a,n) for(int i = a;i >= n;i--)

#define clean(a) memset(a,0,sizeof(a))

const

int inf = 1

<< 30

;typedef

long

long

ll;typedef

double

db;template

void read(t &x)

template

void

write(t x)

struct

node

a[4000014

];int lst[2000005],len = 0

;void add(int x,int

y)int x,y,z,p,n,m,num = 0,ans = 0,top = 0

;int low[2000005],stk[2000005],dfn[2000005],vis[2000005

];int col[2000005

];void tarjan(int

u)

else

if(vis[y])

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

while(u !=v);

}}int

main()

duke(i,

1,2 *n)

if(!dfn[i])

tarjan(i);

int ok = 1

; duke(i,

1,n)

}printf(

"possible\n");

duke(i,

1,n)

printf("\n

");return0;

}/*3 11 1 3 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 問題學習 模板

首先來看這樣一道題 gym 101201f illumination two sat 題目鏈結 題意 乙個n n的房子,有很多燈,每個格仔只能被上下方向照一次 左右方向照一次,每個燈可以選擇上下或是左右照,照明長度以自身位置為中心,占用2 r 1個格仔。問能否安排一種方案,使所有格仔滿足條件。析 典...

2 Sat模板詳解

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