UVa 11294 Wedding (two SAT 输出解)

来源:互联网 发布:工业机器人控制软件 编辑:程序博客网 时间:2024/05/02 02:51

题意:

有n对夫妻,要坐在一张长桌子的两侧,夫妻不能坐在同一侧,其中有一个是公主,她不希望看到她对面一侧的人中有奸夫淫妇。。。题中给出若干对有奸情的两个人,可以是异性也可以是同性。。。问你是否存在满足条件的情况,如果存在,则输出和公主同一侧的人。


解题思路:

two SAT搞起,我用的是刘汝佳的犀利的模板,直接搜环,不用强联通~这个好处就是输出解特方便,不需要强联通缩点加拓扑,好东西!


/* **********************************************Author      : JayYeCreated Time: 2013-10-24 12:13:16File Name   : JayYe.cpp*********************************************** */#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int maxn = 500 + 5;struct twoSAT {    struct Edge {        int to, next;    }edge[maxn*maxn];    int n;    bool mark[maxn<<1];    int S[maxn<<1], c, head[maxn<<1], E;    void init(int n) {        this->n = n;        for(int i = 0;i < n*2; i++) {            head[i] = -1;            mark[i] = false;        }        E = 0;    }    void newedge(int u, int to) {        edge[E].to = to;        edge[E].next = head[u];        head[u] = E++;    }    bool dfs(int u) {        if(mark[u^1])   return false;        if(mark[u]) return true;        mark[u] = true;        S[c++] = u;        for(int i = head[u];i != -1;i = edge[i].next) {            int to = edge[i].to;            if(!dfs(to))    return false;        }        return true;    }    bool solve() {        for(int i = 0;i < n*2;i += 2) if(!mark[i] && !mark[i^1]){            c = 0;            if(!dfs(i)) {                while(c)    mark[S[--c]] = false;                if(!dfs(i+1))   return false;            }        }        return true;    }}sol;int get[33];int main() {    get['w' - 'a'] = 0;    get['h' - 'a'] = 1;    int n, m, a, c;    char b, d;    while(scanf("%d%d", &n, &m) != -1 && n) {        sol.init(n);        sol.newedge(0, 1);        for(int i = 0;i < m; i++) {            scanf("%d%c %d%c", &a, &b, &c, &d);            sol.newedge(a*2 + get[b-'a'], c*2 + (get[d-'a']^1));// 建边            sol.newedge(c*2 + get[d-'a'], a*2 + (get[b-'a']^1));        }        if(sol.solve()) {            for(int i = 2;i < n*2; i += 2) {                if(!sol.mark[i]) printf("%dw%c", i/2, i == n*2-2 ? '\n' : ' ');                else    printf("%dh%c", i/2, i == n*2-2 ? '\n' : ' ');            }        }        else            puts("bad luck");    }    return 0;}


原创粉丝点击