hdoj 1824 Let's go home(2-SAT)

來源:互聯網
上載者:User

標籤:

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1824

思路分析:該問題為2-SAT問題;需要注意邏輯推理的等價性;

(1)題目第一個條件:每一個隊或者隊長留下或者其與兩名隊員同時留下,或者表明只能為兩種情況中的一種;假設三人為A,B,C,隊長為A,0表示不留下,1表示留下,因為B與C同時留下或者不留下,只要B,C中其中一個沒有留下或者留下,則B,C中另一個也同樣留下或者不留下,所以可以從該條件中推匯出六條等價關係,即A不留下->B,C同時留下,A留下->B,C同時不留下,B留下->C留下,A不留下,B留下->C留下,A不留下,C留下->B留下,A不留西,C不留下->B不留下,A留下;

(2)題目中第二個條件:每一對隊員,如果隊員A留下,則B必須回家休息,或者B留下,A必須回家休息;則可以推匯出兩條等價式:A留下->B不留下,B留下->A不留下,注意在這個條件中可以A,B都不留下;

 

代碼如下:

#include <cstdio>#include <vector>#include <cstring>#include <iostream>using namespace std;const int MAX_N = 2 * 5000 + 10;struct TwoSAT {    int n;    vector<int> G[2 * MAX_N];    bool mark[2 * MAX_N];    int S[2 * MAX_N], c;    void Init(int n)    {        this->n = n;        for (int i = 0; i <= 2 * n; ++i)            G[i].clear();        memset(mark, 0, sizeof(mark));    }    bool Dfs(int x)    {        if (mark[x ^ 1])  return false;        if (mark[x])      return true;        mark[x] = true;        S[c++] = x;        for (int i = 0; i < G[x].size(); ++i)        {            if (!Dfs(G[x][i]))                return false;        }        return true;    }    void AddClause(int x, int y)    {        int a = 2 * x;        int b = 2 * y;        G[a ^ 1].push_back(b);        G[b ^ 1].push_back(a);    }    void AddClauseTeam(int i, int j, int k)    {        int a = 2 * i;        int b = 2 * j;        int c = 2 * k;        G[a].push_back(b ^ 1);        G[a].push_back(c ^ 1);        G[b].push_back(a ^ 1);        G[b].push_back(c);        G[c].push_back(a ^ 1);        G[c].push_back(b);        G[a ^ 1].push_back(b);        G[a ^ 1].push_back(c);        G[b ^ 1].push_back(a);        G[b ^ 1].push_back(c ^ 1);        G[c ^ 1].push_back(a);        G[c ^ 1].push_back(b ^ 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]] = false;                    if (!Dfs(i + 1))                        return false;                }            }        }        return true;    }};TwoSAT sat;int main(){    int n, m;    while (scanf("%d %d", &n, &m) != EOF)    {        int a, b, c;        sat.Init(3 * n);        for (int i = 0; i < n; ++i)        {            scanf("%d %d %d", &a, &b, &c);            sat.AddClauseTeam(a, b, c);        }        for (int i = 0; i < m; ++i)        {            scanf("%d %d", &a, &b);            sat.AddClause(a, b);        }        bool ok = sat.Solve();        if (ok)            printf("yes\n");        else            printf("no\n");    }    return 0;}

hdoj 1824 Let's go home(2-SAT)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.