HDU 3062 簡單的2-SAT問題

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   for   art   

在2-SAT,最讓我糾結的還是添加有向線段的函數了

void add_clause(int i,int a,int j,int b)
{
    int m=2*i+a;
    int n=2*j+b;
    G[m^1].push_back(n);
    G[n^1].push_back(m);
}

這裡a,b因為只有真假兩種情況,所以只取0或1,這裡表示m V n是正確的,那麼意思是取到m^1時,那麼n必然得取到

同理取到n^1時,m必然取到,所以兩條有向線段就添加成功了

例如這道題給所有夫妻排好序後,1號夫妻的丈夫,和3號夫妻的妻子有矛盾,那麼來1號的妻子或3號中的丈夫是肯定成立的

那添加量就可以寫成add_clause(1,0,3,1)  (0表示妻子,1表示丈夫)

最後添加進去的就是G[3].push_back(7),G[6].push_back(2);

表示1號的丈夫來了,那隻能讓3號的丈夫來以及

要是3號的妻子來,那麼只能讓1號的妻子來才不會有矛盾

bool solve()
{
    for(int i=0;i<2*n;i+=2){
        if(!mark[i]&&!mark[i^1]){
            c=0;
            if(!dfs(i)){
                while(c>0) mark[S[--c]]=0;
                if(!dfs(i^1)) return false;
            }
        }

    }
    return true;
}

solve()中尋找遍所有的夫妻對,表示若且唯若夫妻二人都不能來的時候返回false,否則返回true

總代碼如下:

#include <cstdio>#include <cstring>#include <vector>using namespace std;#define N 1005*2bool mark[N];vector<int> G[N];int n,c,S[N];bool dfs(int i){    if(mark[i^1]) return false;    if(mark[i]) return true;    mark[i]=true;    S[c++]=i;    for(int j=0;j<G[i].size();j++)        if(!dfs(G[i][j])) return false;    return true;}void init(){    for(int i=0;i<N;i++) G[i].clear();    memset(mark,false,sizeof(mark));    memset(S,0,sizeof(S));}void add_clause(int i,int a,int j,int b){    int m=2*i+a;    int n=2*j+b;    G[m^1].push_back(n);    G[n^1].push_back(m);}bool solve(){    for(int i=0;i<2*n;i+=2){        if(!mark[i]&&!mark[i^1]){            c=0;            if(!dfs(i)){                while(c>0) mark[S[--c]]=0;                if(!dfs(i^1)) return false;            }        }    }    return true;}int main(){    int m,a1,a2,c1,c2;    while(scanf("%d%d",&n,&m)!=EOF){        init();        for(int i=0;i<m;i++){            scanf("%d%d%d%d",&a1,&a2,&c1,&c2);            add_clause(a1,c1^1,a2,c2^1);        }        if(solve()) printf("YES\n");        else printf("NO\n");    }    return 0;}
View Code

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.