NOI2017 遊戲與2 sat方案輸出

2022-08-16 18:12:16 字數 2331 閱讀 6074

本文介紹了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 的點,然後在球方案的時候判一下 ...