POJ 3648 2-SAT

来源:互联网 发布:手机能不能做淘宝客服 编辑:程序博客网 时间:2024/06/18 13:34

POJ 3648

题目链接:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17198

题意:

n对夫妇,其中0号夫妇为新婚夫妇。新娘由于带着婚纱只能看到对面的人。

现在安排座位,座位的规则是不坐左边就坐右边。要求一对夫妇不能同时坐一边,而且一些有特殊关系的人不能坐在新娘的的对面。

输出可能坐在新娘这边的夫或者妇,按编号顺序输出。

思路:

2-SAT版,当然要重新编辑一下。

首先bride是新娘而不是新郎。

设坐在新娘这边而TRUE,坐对面为FALSE。剩下任务就是套版。

源码:

#include <cstdio>

#include <cstring>

#include <cmath>

#include <cstdlib>

#include <algorithm>

#include <iostream>

#include <queue>

#include <vector>

#include <stack>

using namespace std;

const int MAXN = 1000 + 5;

vector<int>lin[MAXN];

stack<int>sta;

int valid[MAXN];

char str[10];

int n, m;

//int cal()

//{

//    int len = strlen(str);

//    int ans = 0;

//    for(int i = 0 ; i < len - 1 ; i++)

//        ans = ans * 10 + str[i] - '0';

//    ans = ans * 2;

//    if(str[len - 1] == 'w')

//        ans += 1;

//    return ans;

//}

bool dfs(int u)

{

//    printf("u = %d\n", u);

    if(valid[u^1])  return false;

    if(valid[u])    return true;

    valid[u] = true;

    sta.push(u);

    for(int i = 0 ; i < (int)lin[u].size() ; i++){

        int v = lin[u][i];

//        printf("v = %d\n\n", v);

        if(!dfs(v)) return false;

    }

    return true;

}

bool ok()

{

    while(!sta.empty()) sta.pop();

    memset(valid, false, sizeof(valid));

    for(int i = 0 ; i < 2 * n ; i+=2){

        if(!valid[i] && !valid[i^1]){

//            printf("i = %d\n", i);

            if(i == 0){

                if(!dfs(1)) return false;

            }

            else{

                if(!dfs(i)){

    //                printf("i = %d\n", i);

                    while(!sta.empty()){

                        int org = sta.top();    sta.pop();

                        valid[org] = false;

                        if(org == i)

                            break;

                    }

                    if(!dfs(i^1))  return false;

                }

            }

        }

    }

    return true;

}

int main()

{

    while(scanf("%d%d", &n, &m) != EOF && n + m){

        for(int i = 0 ; i < 2 * n ; i++)

            lin[i].clear();

        int u, v;

        getchar();

        for(int i = 1 ; i <= m ; i++){

            int flag = 0;

            int u, v;

            char op1, op2;

            scanf("%d%c %d%c", &u, &op1, &v, &op2);

            u *= 2, v *= 2;

            if(op1 == 'w')  u += 1;

            if(op2 == 'w')  v += 1;

//            printf("u = %d, v = %d\n", u, v);

//            printf("u^1 = %d, v^1 = %d\n", u ^ 1, v ^ 1);

            lin[u^1].push_back(v);

            lin[v^1].push_back(u);

        }

//        for(int i = 0 ; i < 2 * n ; i++){

//            printf("i = %d, j = ", i);

//            for(int j = 0 ; j < (int)lin[i].size() ; j++)

//                printf("%d ", lin[i][j]);

//            printf("\n");

//        }

        memset(valid, false, sizeof(valid));

        if(ok()){

            int f = 1;

            for(int i = 2 ; i < 2 * n ; i += 2){

                if(f)   f = 0;

                else    printf(" ");

                printf("%d", i / 2);

                if(valid[i])    printf("h");

                else    printf("w");

            }

            printf("\n");

        }

        else

            printf("bad luck\n");

    }

    return 0;

}

 

版版~

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <cmath>

#include <algorithm>

#include <iostream>

#include <string>

#include <queue>

#include <stack>

#include <vector>

using namespace std;

const int MAXN = 1005;

struct TwoSAT

{

    int n;

    vector<int> G[MAXN * 2];

    bool valid[MAXN * 2];

    int S[MAXN * 2], c;

 

    bool dfs(int x)

    {

        if(valid[x ^ 1])    return false;

        if(valid[x])    return true;

        valid[x] = true;

        S[c++] = x;

        for(int i = 0 ; i < (int)G[x].size() ; i++)

            if(!dfs(G[x][i]))   return false;

        return true;

    }

 

    void init(int n)

    {

        this->n = n;

        for(int i = 0 ; i < n * 2 ; i++)    G[i].clear();

        memset(valid, false, sizeof(valid));

    }

 

    void add_clause(int x ,int xval, int y, int yval)

    {

        x = x * 2 + xval;

        y = y * 2 + yval;

        G[x^1].push_back(y);

        G[y^1].push_back(x);

    }

 

    bool solve()

    {

        for(int i = 0 ; i < n * 2 ; i+=2){

            if(!valid[i] && !valid[i^1]){

                c = 0;

                if(i > 0){

                    if(!dfs(i)){

                        while(c > 0)    valid[S[--c]] = false;

                        if(!dfs(i + 1)) return false;

                    }

                }

                else{

                    if(!dfs(i)) return false;

                }

            }

        }

        return true;

    }

};

int main()

{

    int n, m;

    while(scanf("%d%d", &n, &m) != EOF && n + m){

        TwoSAT lv;

        lv.init(n);

        int u, v;

        char op1, op2;

        for(int i = 1 ; i <= m ; i++){

            scanf("%d%c %d%c", &u, &op1, &v, &op2);

            int uval = op1 == 'w' ? 0 : 1;

            int vval = op2 == 'w' ? 0 : 1;

            lv.add_clause(u, uval, v, vval);

        }

        if(lv.solve()){

            int f = 1;

            for(int i = 2 ; i < 2 * n ; i+=2){

                if(f)   f = 0;

                else    printf(" ");

                printf("%d", i/2);

                if(lv.valid[i]) printf("w");

                else    printf("h");

            }

            printf("\n");

        }

        else

            printf("bad luck\n");

    }

    return 0;

}

 

 

0 0
原创粉丝点击