本文介紹了2-sat輸出一種方案的方法與證明,以及一種 $ o(nm) $ 複雜度輸出最小字典序的方法.
先判定是否有解,縮點後得到一張dag.對於命題組 $ (i,i') $ ,我們選擇 $ i $ 和 $ i' $ 中拓樸序靠後的乙個即可.
同時由於tarjan縮點時本來就是拓樸序倒序縮點的,只需要選擇 $ i $ 和 $ i' $ 中所屬強連通分量中編號小的那個即可.
下面證明這種方案的正確性.我們使用反證法.
假如這樣的做法不對,也就是說,會存在一條邊 $ (u,v) $ ,使得命題 $ u $ 為 $ true $ 而命題 $ v $ 為 $ false $ .
因為命題 $ u $ 為 $ true $ ,我們得到命題 $ u' $ 的拓撲序在命題 $ u $ 之前.因為存在邊 $ (u,v) $ ,我們得到命題 $ u $ 的拓撲序在命題 $ v $ 之前.而2-sat問題具有對稱性,即逆否命題之間真假性相同.如果選 $ u $ 則必須選 $ v $ ,反過來如果不選 $ v $ 則一定不能選 $ u $ ,所以就存在邊 $ (v',u') $ ,從而拓撲序的順序應該是 $ (v',u',u,v) $ , 那麼 $ v $ 的拓撲序在 $ v' $ 之後,這與 $ v $ 為 $ false $ 矛盾.
從一號點開始,先強制它為 $ true $ ,如果無解再強制它為 $ false $ ,乙個乙個確定下去即可.
有三種賽車 $ a $ , $ b $ , $ c $ 和四種地圖 $ a $ , $ b $ , $ c $ , $ x $ .地圖 $ a/b/c $ 表示不能用賽車 $ a/b/c $ ,地圖 $ x $ 可以用任意賽車.現有 $ n $ 張地圖和 $ m $ 個限制,第 $ i $ 個限制形如:如果圖 $ x $ 選擇了賽車 $ u $ ,那麼圖 $ y $ 就必須選擇賽車 $ v $ .要求判定是否有解,有解輸出任意一種方案.
資料範圍:設 $ x $ 型地圖有 $ d $ 張, $ n,m≤100000,d≤8 $
$ x $ 型地圖可以看做在 $ a $ 型地圖和 $ b $ 型地圖中任選乙個, $ 2^d $ 列舉一下.
剩下的就是直接 $ 2-sat $ 跑一下輸出方案.
注意命題和它的逆否命題要同時加入.
#pragma gcc optimize("2,ofast,inline")
#define fi first
#define se second
#define ll long long
#define pb push_back
#define mp make_pair
#define pii pair#includeusing namespace std;
const int n = 3e5 + 10;
const int mod = 1e9 + 7;
template void read(t &x)
int n, m, d, e, v;
int a[n], b[n], s[n];
int u[n], v[n];
char s[n];
int fir[n], nex[n << 1], arr[n << 1], num[n][3];
int tim, sccn, scc[n], low[n], dfn[n];
stackst;
inline void add_edge(int x, int y)
void dfs(int x)
else if (!scc[arr[i]]) low[x] = min(low[x], dfn[arr[i]]);
} if (low[x] == dfn[x]) while (y != x); }}
void check()
} for (int i = 1; i <= m; ++i)
}add_edge(num[a[i]][u[i]], num[a[i]][o]);
add_edge(num[a[i]][o] ^ 1, num[a[i]][u[i]] ^ 1);
} else
} sccn = tim = 0;
for (int i = 1; i <= v; ++i)
for (int i = 1; i <= n; ++i)
for (int i = 1; i <= n; ++i)
puts("");
exit(0);
}void dfs(int x)
}int main()
read(m);
for (int i = 1; i <= m; ++i)
dfs(1);
puts("-1");
return 0;
}
NOI2017 遊戲(2 SAT 列舉)
2 sat板子題 如果沒有x這個字元的話,問題變成每個點都有兩種選法,有一些限制,顯然是個2 sat問題,設拆出來的兩個點分別為 i 和 i 則對於限制 x y 連邊 x,y y x 跑tarjan即可 2 sat基操嘛。即使現在有了x這個字元,我們也可以假裝乙個點仍只有兩種選法,列舉這兩種選法,並...
NOI2017 遊戲 2 sat演算法
題目 libreoj 題意 n場遊戲,有三種車abc,給定長度為n的字串,a 表示不能選a,b c 同理,x 表示不限,至多d個 x 有m個限制 i,hi,j,hj 表示如果第i場選擇車hi,那麼第j場必須選擇車hj。求可行方案,或無解。n 10 5,d 8。演算法 2 sat 題解 列舉 x 是 ...
NOI2017 遊戲 解題報告
d 這麼小,你考慮直接對 d 個東西暴力 列舉 x 為 a 或 b c 就不用了,因為 a,b 已經包含 c 了,剩下的就是個 2 sat 問題了 但是你發現有個情況是,在若 a 即 b 時,如果 b 被 ban 了,那麼 a 也要被 ban 我們記錄一下被 ban 的點,然後在球方案的時候判一下 ...