POJ 3678 深刻理解2SAT

2021-06-21 10:22:35 字數 2070 閱讀 3750

感覺:這題看了一晚上了,看了所有的解題報告才明天怎麼回事……昨天自學沒理解好2sat啊,所以連邊不知道怎麼連,而且看了別人的解題報告了也看不明白為什麼要那樣連,暈……

思路:因為給出結點 a ,b,值 c,還有判斷方式op,這種一看當然就知道是用2sat做了。為什麼說是深刻理解2sat呢,因為……2sat中說過,只有關係確定的才能連邊,否則不能連邊;還有乙個重要的是,如果某個條件必須為某個值時,自身與自身的相反條件也要連邊,具體看下面解釋:

現在設 2*a為1,2*a+1為0;當然 2*b為1,2*b+1為0:

1.當op為』and『時:

(1)當c=1時,那麼只有a 與 b同時為1時,a  and b才等於1,並且有且只有當a與b都為1時這個條件才成立,所以a與b一定要等1,所以連邊<2*a+1,2*a>,<2*b+1,2*b>,表示不管怎麼樣,a與b的情況都等於1,即:當a等於0時a必等於1,b等於0時b必等於1,這個剛開始我看別人的解題報告就是這麼說的,然後自己也沒太理解,其實真正的內涵就是強制執行a與b都等於1 !(如果a等於1了的話當然這條邊就沒用了,如果a等於0的話,那麼這條連就可以起到把a強制等於1以符合題目條件情況了,就是如此簡單,得慢慢理解)

(2)當c=0時,那麼當a等於0時,b可能為0也可以為1,所以是不確定關係,由上面說的一定是確定關係才能連邊,所以a為0的情況就不能連邊了;當a等於1時,b一定為0才能使 a and b =0,所以連邊:<2*a,2*b+1>,當然還有<2*b,2*a,+1>。

2.當op為or時,

(1)當c=1時,那麼當a=1時,b=1或者b=0,所以當a=1時出現了兩種關係,就是不確定了,就不用連邊了;當a=0時,那麼b一定=1,所以是確定關係,連邊:<2*a+1,2*b>,當然還有<2*b+1,2*a>。

(2)當c=0時,那麼只有當a=b=0這個關係,所以這個和上面1(1)情況就一樣了,上面是強制執行a=b=1的情況,而這裡因為只有a=b=0的情況,所以也要強制執行a=b=0,即連邊:<2*a,2*a+1>,<2*b,2*b+1>。

3.當op為xor時,因為如果a=1,那麼b必=0;a=0,b必=1;b=1,a必=0;b=0,a必=1。如此看,這四個關係都是確定的,所以都要連邊,但是其實我們可以不連,一條邊都不用連,因為出a=1的時候一定不會再出現a=0了,這四條邊是不會產生矛盾的,所以強連通縮點後不會出現belong[2*a]=belong[2*a+1]的情況的,所以連了也沒用,只是多加了點判斷的時間罷了……這在別人的解題報告裡說的是形成了組環了,都是乙個意思。比如:a=1,b=0與b=0,a=1在tarjan中會形成乙個新的結點,也就是自環,所以……在異或這種情況中只能選擇a=0或者a=1,所以不會出現矛盾……故不用連邊了!

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define pi acos(-1.0)

#define mem(a,b) memset(a,b,sizeof(a))

#define sca(a) scanf("%d",&a)

#define sc(a,b) scanf("%d%d",&a,&b)

#define pri(a) printf("%d\n",a)

#define lson i<<1,l,mid

#define rson i<<1|1,mid+1,r

#define mm 200005

#define mn 2010

#define inf 1000000007

#define eps 1e-7

using namespace std;

typedef long long ll;

int dfn[mn],vis[mn],low[mn],stack[mn*10],belong[mn],tem,count,top;

vectore[mn];

void tarjan(int u)

{ dfn[u]=low[u]=++tem;

vis[u]=true;

stack[++top]=u;

int v,i,l=e[u].size();

for(i=0;i

POJ 3678(拓撲排序 優先佇列)

poj 3678 1 題意 給出n個點,每個點都有乙個重量值有兩個限制條件,一是n個點每個點的重量都不一樣 二是m個限制中有a求的重量小於b球的重量。而且盡可能讓求的質量小一點,每個從1 n每次盡量讓這個求的質量小一些。如果結果存在,輸出n個點的質量,否則輸出 1.2 思路 一開始以為是差分約束,後...

深刻理解IdentityHashMap

新建pojo package test public class cat public string getname public void setname string name public integer getage public void setage integer age public...

深刻理解IdentityHashMap

新建pojo package test public class cat public string getname public void setname string name public integer getage public void setage integer age public...